Screenshooting tool

Post your working scripts, libraries and tools for AHK v1.1 and older
AtleastItried
Posts: 51
Joined: 03 Mar 2017, 04:51

Screenshooting tool

06 Mar 2017, 13:35

One of my more interesting creation that are actually working is the screenshot tool. It used the windows 10 Snipping tool so you will need that.

Here is what it does:

Win+A: Selected area is copied to clipboard
Win+Shift+A: Selected area is pasted into paint
Win+Shift+S: Opens a save window of the selected area

If you like this and want to support me... well idk what to do. Also, sorry for the really messy code.

TBA: I will change the saving option to send an alt f4 instead of ctrl s so paint closes after saving.

Code: Select all


#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#notrayicon
<#a:: 
Loop, 20
{

If Winactive("Snipping Tool"){
break
}else{
Run, SnippingTool.exe
}

sleep 10
}


sendInput ^n
Wait1:
WinWaitActive,ahk_class Microsoft-Windows-Tablet-SnipperEditor,,5
if (ErrorLevel=1){		
GetKeyState, KST, LButton
if (KST="U") {
If Winactive("Snipping Tool"){
Goto Wait1
}else{
return
}
}
else{
Goto Wait1
}
}
Winclose, Snipping Tool
Winclose, Snipping Tool
Return

<#+a:: 
Loop, 20
{

If Winactive("Snipping Tool"){
break
}else{
Run, SnippingTool.exe
}

sleep 10
}
sleep 10

sendInput ^n

Wait2:
WinWaitActive,ahk_class Microsoft-Windows-Tablet-SnipperEditor,,5
if (ErrorLevel=1){		
GetKeyState, KST, LButton
if (KST="U") {
If Winactive("Snipping Tool"){
Goto Wait1
}else{
return
}
}
else{
Goto Wait2
}
}

Winclose, Snipping Tool
Winclose, Snipping Tool
Run, msPaint.exe
Loop, 50
{

If Winactive("Paint"){
break
}else{

WinActivate Paint
}

sleep 50
}
WinMaximize, Paint
sendInput ^v
Return

<#+s:: 


Loop, 20
{

If Winactive("Snipping Tool"){
break
}else{
Run, SnippingTool.exe
}

sleep 10
}
sleep 10

sendInput ^n
Wait3:
WinWaitActive,ahk_class Microsoft-Windows-Tablet-SnipperEditor,,5
if (ErrorLevel=1){		
GetKeyState, KST, LButton
if (KST="U") {
If Winactive("Snipping Tool"){
Goto Wait1
}else{
return
}
}
else{
Goto Wait3
}
}
Winclose, Snipping Tool
Winclose, Snipping Tool
Run, msPaint.exe
Loop, 50
{

If Winactive("Paint"){
break
}else{

WinActivate Paint
}

sleep 50
}
WinMaximize, Paint
sendInput ^v
sendInput ^s

Return[list][/list]
BreakTheWind
Posts: 5
Joined: 19 May 2017, 04:14

Re: Screenshooting tool

21 May 2017, 05:45

Thank you!
fenchai
Posts: 292
Joined: 28 Mar 2016, 07:57

Re: Screenshooting tool

24 May 2017, 18:40

cool! thank you for this now I only need something that can upload to imgur quickly and my life is done.
User avatar
runie
Posts: 304
Joined: 03 May 2014, 14:50
Contact:

Re: Screenshooting tool

24 May 2017, 19:01

This has an imgur uploader if you want to use it or study the code: https://autohotkey.com/boards/viewtopic.php?f=6&t=30007
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: Screenshooting tool

25 May 2017, 01:57

The below code is what I use to make the Windows Snipping Tool a little easier to use.

Win+X will start the Snipping Tool if it is not running and put it in the mode to select a new snippet. If Snipping is active it minimizes. If Snipping is minimized or not active it restores it.

The Snipping Tool behaves different in Windows 10 from previous Windows so it detects the OS and adjust.

Code: Select all

; Quick Tools
; Fanatic Guru
; 2016 03 14
;
; Shortcuts to bring up Windows Tools
;
;{-----------------------------------------------
; Window+X          Open/Activate/Minimize Windows Snipping Tool
; Window+Numpad 0   Open/Activate/Minimize Windows Calculator
;}

; INITIALIZATION - ENVIROMENT
;{-----------------------------------------------
;
#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  ; Ensures that only the last executed instance of script is running
;}

; HOTKEYS
;{-----------------------------------------------
;
#x::	; <-- Open/Activate/Minimize Windows Snipping Tool
{
	if WinExist("ahk_class Microsoft-Windows-Tablet-SnipperToolbar")
	{
		WinGet, State, MinMax
		if (State = -1)
		{	
			WinRestore
			Send, ^n
		}
		else if WinActive()
			WinMinimize
		else
		{
			WinActivate
			Send, ^n
		}
	}
	else if WinExist("ahk_class Microsoft-Windows-Tablet-SnipperEditor")
	{
		WinGet, State, MinMax
		if (State = -1)
			WinRestore
		else if WinActive()
			WinMinimize
		else
			WinActivate
	}
	else
	{
		Run, snippingtool.exe
		if (SubStr(A_OSVersion,1,2)=10)
		{
			WinWait, ahk_class Microsoft-Windows-Tablet-SnipperToolbar,,3
			Send, ^n
		}
	}
	return
}

#numpad0::	; <-- Open/Activate/Minimize Windows Calculator
{
	if WinExist("Calculator ahk_class CalcFrame") or WinExist("Calculator ahk_class ApplicationFrameWindow")
		if WinActive()
			WinMinimize
		else
			WinActivate
	else
		Run calc.exe
	return
}
;}
There is a similar hotkey for using the Windows Calculator. The ability to hit Win+Numpad0 has allowed me to get rid of my desktop calculator. I use this many times each day.

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
fenchai
Posts: 292
Joined: 28 Mar 2016, 07:57

Re: Screenshooting tool

25 May 2017, 19:49

Run1e wrote:This has an imgur uploader if you want to use it or study the code: https://autohotkey.com/boards/viewtopic.php?f=6&t=30007
for how long does it stay uploaded in their database? I googled and found its 6 months if no view then other thread said permanent unless deletion is requested.
User avatar
runie
Posts: 304
Joined: 03 May 2014, 14:50
Contact:

Re: Screenshooting tool

25 May 2017, 23:28

fenchai wrote:for how long does it stay uploaded in their database? I googled and found its 6 months if no view then other thread said permanent unless deletion is requested.
You could log in to your account with OAuth2.0 through the API and the picture will stay forever. I decided not to do that for the public version Power Play because I'd have to handle sensitive data.
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: Screenshooting tool

26 May 2017, 01:14

Below is a screen clipping script that I use that also allows automatic uploading to Imgur.

There is a Help if you right click on the tray icon. Also you can right click on a clipping and use a context menu to do things with a clip.

Basic usage is just hold Window key and left mouse drag.

There is a function called Imgur_Post that could easily be used in any script to upload images anonymously to Imgur. You have to get a client token to upload. The code for uploading to a specific account is not included. I believe I know how to code this but never went to the trouble to implement it as it requires a client secret token that is only good for 30 days then you have to go through a process to get another one. To be useful I would have to automate the process for getting this secret token which seemed like too much trouble.

I also intended to have some type of cropping of a screen clip or restricting a screen clip to a certain size or ratio but again never got around to it.

Code: Select all

; Screen Clipper
; Fanatic Guru
; 2017 02 25
; Version 1.00
;
; Use Mouse Drag to Clip Selection of Screen
;
;{-----------------------------------------------
;
; Credits:
;
; Learning one	:=Screen Clipping
;		https://autohotkey.com/boards/viewtopic.php?f=6&t=12088
; Joe Glines		:= added Clip, IMGUR, Email parameters to ScreenClip2Win()
; maestrith		:= IMGUR upload
;		https://autohotkey.com/board/topic/95521-ahk-11-upload-a-screen-capture-to-imgur/
; tervon 			:= closing of clip window
;
;}

; INITIALIZATION - ENVIROMENT
;{-----------------------------------------------
;
#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  ; Ensures that only the last executed instance of script is running
;}

; INITIALIZATION - VARIABLES
;{-----------------------------------------------
;
 ;Obtain IMGUR API token value here: https://imgur.com/account/settings
Settings_Imgur_Client := "xxxxxxxxxxxxxx" ; Add client token here
Settings_SavePath := ".\Images - Screen Clipper\"
RelativePath(Settings_SavePath)
Settings_Ini := A_ScriptFullPath ": Screen Clipper.ini" ; Ini File in Script's Alternate Data Stream (requires NTFS)
Settings_Ini := A_ScriptDir "\Screen Clipper.ini" ; Normal Ini File

; Read Settings from Ini File
if FileExist(Settings_Ini)
{
	IniRead, Settings_Imgur_Client, %Settings_Ini%, Settings, Settings_Imgur_Client, %Settings_Imgur_Client%
	IniRead, Settings_SavePath, %Settings_Ini%, Settings, Settings_SavePath, %Settings_SavePath%
}

; Read Hotkeys from Script File
FileRead, Script, %A_ScriptFullPath%
Script :=  RegExReplace(Script, "ms`a)^\s*/\*.*?^\s*\*/\s*|^\s*\(.*?^\s*\)\s*")
Hotkeys := {}
Loop, Parse, Script, `n, `r
	if RegExMatch(A_LoopField,"^\s*(.*):`:.*`;\s*(.*)",Match)
	{
		if !RegExMatch(Match1,"(Shift|Alt|Ctrl|Win)")
		{
			StringReplace, Match1, Match1, +, Shift+
			StringReplace, Match1, Match1, <^>!, AltGr+
			StringReplace, Match1, Match1, <, Left, All
			StringReplace, Match1, Match1, >, Right, All 
			StringReplace, Match1, Match1, !, Alt+
			StringReplace, Match1, Match1, ^, Ctrl+
			StringReplace, Match1, Match1, #, Win+
		}
		Hotkeys.Push({"Hotkey":Match1, "Comment":Match2})
	}

;}

; INITIALIZATION - GUI
;{-----------------------------------------------
;
Menu, tray, icon, %A_WinDir%\system32\mmcndmgr.dll,106
;******************Tray Menu items***********
Menu, Tray, NoStandard ;removes default options
Menu, Tray, Add , Help, Help ;can doubleclick main
Menu, Tray, Default, Help ;sets to default
Menu, Tray, Add, Settings
Menu, Tray, Add, 
Menu, Tray, Add, Suspend
Menu, Tray, Add, Reload
Menu, Tray, Add, Edit
Menu, Tray, Add, Exit

Gui, +AlwaysOnTop +resize
Gui, Help:Default
Gui, Color, aqua
for Index, Element in Hotkeys
{
	Gui, Font, Bold
	Loop, Parse, % Element.Hotkey, +
	{
		If  (A_LoopField = "Win")
		{
			Gui, Font, cBlue
			xx := 40
		}
		else if (A_LoopField = "Alt")
		{
			Gui, Font, cRed
			xx := 75
		}
		else if (A_LoopField = "Ctrl")
		{
			Gui, Font, cGreen
			xx := 110
		}
		else if (A_LoopField = "Shift")
		{
			Gui, Font, cYellow
			xx := 5
		}
		else
		{
			Gui, Font, Bold cBlack
			xx := 145
		}
		if (A_Index = 1)
			Gui, Add, Text, x%xx% , % Format("{:Ts}", A_LoopField)
		else
			Gui, Add, Text, x%xx% yp , % Format("{:Ts}", A_LoopField)
	}
	Gui, Font
	Gui, Add, Text, yp x200, % Element.Comment
}

Gui, Settings:Default
Gui, Font, s10 bold
Gui, Add, Text, , Enter Path to Save Clips:
Gui, Font
Gui, Add, Edit, w500 vSettings_SavePath, %Settings_SavePath%
Gui, Add, Button, gSettings_ButtonPath yp x510 w22 h22 hwndIcon
GuiButtonIcon(Icon, "shell32.dll", 46, "s20")
Gui, Add, Text, x8, Starting ".\" indicates to start Relative Path in current folder.
Gui, Add, Text, yp+15,   Each additional "." indicates to start Relative Path up one folder
Gui, Add, Text, yp+15,   Example:  .\Images         (will store images in a subfolder of the working folder named "Images" )
Gui, Font, bold
Gui, Add, Text, yp+40, Enter Imgur Client ID:
Gui, Font
Gui, Add, Edit, yp-4 x140 w125 vSettings_Imgur_Client, %Settings_Imgur_Client%
Gui, Add, Button, yp+50 x100 w120 gSettings_ButtonSave, SAVE Settings
Gui, Add, Button, yp x300 w120 gSettings_ButtonUse Default, USE Settings

Menu, Context_Clip, add, COPY:  Clipboard, Context_Clip_Handler
Menu, Context_Clip, add, COPY:  Clipboard with Border, Context_Clip_Handler
Menu, Context_Clip, add, COPY:  File, Context_Clip_Handler
Menu, Context_Clip, add, COPY:  File with Border, Context_Clip_Handler
Menu, Context_Clip, add, COPY:  File && Email, Context_Clip_Handler
Menu, Context_Clip, add, COPY:  File && Imgur, Context_Clip_Handler
Menu, Context_Clip, add, COPY:  File`, Imgur && Email, Context_Clip_Handler
Menu, Context_Clip, add
Menu, Context_Clip, add, CLOSE:  Clip Image, Context_Clip_Handler

;}

; BEGINNING OF AUTO-EXECUTE
;{-----------------------------------------------
;

;
;}-----------------------------------------------
; END OF AUTO-EXECUTE

; HOTKEYS
;{-----------------------------------------------
;
#Lbutton::		;	<-- Clip Image Only
	SCW_ScreenClip2Win(SetClipboard:=false)
return

#^Lbutton::	;	<-- Clip Image and Copy to Clipboard
	SCW_ScreenClip2Win(SetClipboard:=true)
return

#!Lbutton::		;	<-- Clip Image and Save to File
	Hwnd := SCW_ScreenClip2Win(SetClipboard:=false)
	MsgBox % Settings_SavePath
	SCW_Win2File(,Hwnd)
return

#^!Lbutton::	;	<-- Clip Image, Copy to Clipboard, and Save to File
	Hwnd := SCW_ScreenClip2Win(SetClipboard:=true)
	SCW_Win2File(,Hwnd)
return

#IfWinActive, ScreenClipperWindow ahk_class AutoHotkeyGUI
	^c::				;	<-- (Screen Clipper) : Copy Active Clip to Clipboard
		SCW_Win2Clipboard()
	return
	+^c::			;	<-- (Screen Clipper) : Copy Active Clip to Clipboard with Border
		SCW_Win2Clipboard(0)
	return
	^s::				;	<-- (Screen Clipper) : Save Active Clip to File
		SCW_Win2File()
	return
	+^s::			;	<-- (Screen Clipper) : Save Active Clip to File with Border
		SCW_Win2File(,0)
	return
	#e::				;	<-- (Screen Clipper) : Save Active Clip to File and Email
		File := SCW_Win2File()
		Email_AttachFile(File)
	return
	#i::				;	<-- (Screen Clipper) : Save Active Clip to File and Post to IMGUR
		File := SCW_Win2File()
		URL := Imgur_Post(File, Settings_Imgur_Client)
		Clipboard := URL
	return
	#^i::				;	<-- (Screen Clipper) : Save Active Clip to File, Post to IMGUR and Email
		File := SCW_Win2File()
		URL := Imgur_Post(File, Settings_Imgur_Client)
		Email_AttachFile(File, URL)
	return
	RButton::	;	<-- (Screen Clipper) : Single for Menu, Double to Close Active Clip
		KeyWait, RButton			; wait release
		KeyWait, RButton, D T0.2	; and pressed again within 0.2 seconds
		if ErrorLevel ; timed-out (only a single press)
			Menu, Context_Clip, Show
		else
			WinClose, A
	return
	Esc::				;	<-- (Screen Clipper) : Close Active Clip
		WinClose, A
	return
#IfWinActive
;}

; SUBROUTINES
;{-----------------------------------------------
;

;}

; SUBROUTINES - GUI
;{-----------------------------------------------
;
Settings_ButtonPath:
	FileSelectFolder, Settings_SavePath, *%Settings_SavePath%, 3, Select Folder for Saved Image
	GuiControl, Settings:, Settings_SavePath, %Settings_SavePath%\
return
Settings_ButtonUSE:
	Gui, Settings:Submit
return
Settings_ButtonSAVE:
	Gui, Settings:Submit
	IniWrite, %Settings_Imgur_Client%, %Settings_Ini%, Settings, Settings_Imgur_Client
	IniWrite, %Settings_SavePath%, %Settings_Ini%, Settings, Settings_SavePath
return
HelpGuiEscape:
HelpGuiClose:
	Gui, Help:Hide
Return

;~ Context Menu for Clip Window
Context_Clip_Handler:
		if (A_ThisMenuItemPos = 9) ; Close Clip Image
			WinClose, A
		Sleep 350	; Context Menu selection fades out and needs time to disappear before Clipping
		if  (A_ThisMenuItemPos = 1)		; Clipboard
			SCW_Win2Clipboard()
		else if (A_ThisMenuItemPos = 2)	; Clipboard with Border
			SCW_Win2Clipboard(0)
		else if (A_ThisMenuItemPos = 3) ; File
			SCW_Win2File()
		else if (A_ThisMenuItemPos = 4) ; File with Border
			SCW_Win2File(,0)
		else if (A_ThisMenuItemPos = 5) ; File & Email
		{
			File := SCW_Win2File()
			Email_AttachFile(File)
		}
		else if (A_ThisMenuItemPos = 6) ; File & Imgur
		{
			File := SCW_Win2File()
			URL := Imgur_Post(File, Settings_Imgur_Client)
			Clipboard := URL
		}
		else if (A_ThisMenuItemPos = 7) ; File, Imgur & Email
		{
			File := SCW_Win2File()
			URL := Imgur_Post(File, Settings_Imgur_Client)
			Email_AttachFile(File, URL)
		}
		
	;~ MsgBox You selected %A_ThisMenuItemPos% - %A_ThisMenuItem% from the menu %A_ThisMenu%.
return

;~ Tray Menu
Help:
	Gui,Help:Show, , Help
return
Settings:
	Gui,Settings:Show, , Settings
return
Suspend:
	Suspend
Return
Reload:
	Reload
Return
Edit:
	Edit
Return
Exit:
	ExitApp
Return
;}

; FUNCTIONS
;{-----------------------------------------------
;
;{vvvvv SCW Functions vvvvv
/*
[module/script] ScreenClip2Win
Author:      Learning one
Thanks:      Tic, HotKeyIt

Creates always on top layered windows from screen clippings. Click in upper right corner to close win. Click and drag to move it.
Uses Gdip.ahk by Tic.

#Include ScreenClip2Win.ahk    						; by Learning one
;=== Short documentation ===
SCW_ScreenClip2Win(SetClipboard:=0) 		; creates always on top window from screen clipping. Click and drag to select area.
SCW_DestroyAllClipWins()								; destroys all screen clipping windows.
SCW_Win2Clipboard(DeleteBorders:=1)			; copies window to clipboard. By default, removes borders. To keep borders, specify "SCW_Win2Clipboard(0)"
SCW_SetUp(Options="")		; you can change some default options in Auto-execute part of script. Syntax: "<option>.<value>"
	StartAfter - module will start to consume GUIs for screen clipping windows after specified GUI number. Default: 80
	MaxGuis - maximum number of screen clipping windows. Default: 6
	BorderAColor - Default: ff6666ff (ARGB format)
	BorderBColor - Default: ffffffff (ARGB format)
	DrawCloseButton - on/off draw "Close Button" on screen clipping windows. Default: 0 (off)
	AutoMonitorWM_LBUTTONDOWN - on/off automatic monitoring of WM_LBUTTONDOWN message. Default: 1 (on)
	SelColor - selection color. Default: Yellow
	SelTrans - selection transparency. Default: 80

	Example:   SCW_SetUp("MaxGuis.30 StartAfter.50 BorderAColor.ff000000 BorderBColor.ffffff00")

;=== Avoid OnMessage(0x201, "WM_LBUTTONDOWN") collision example===
Gui, Show, w200 h200
SCW_SetUp("AutoMonitorWM_LBUTTONDOWN.0")   ; turn off auto monitoring WM_LBUTTONDOWN
OnMessage(0x201, "WM_LBUTTONDOWN")   ; manualy monitor WM_LBUTTONDOWN
Return

^Lbutton::SCW_ScreenClip2Win()   ; click & drag
Esc::ExitApp

#Include Gdip.ahk      ; by Tic
#Include ScreenClip2Win.ahk      ; by Learning one
WM_LBUTTONDOWN() {
	if SCW_LBUTTONDOWN()   ; LBUTTONDOWN on module's screen clipping windows - isolate - it's module's buissines
		return
	else   ; LBUTTONDOWN on other windows created by script
		MsgBox,,, You clicked on script's window not created by this module,1
}
*/

SCW_Version()
{
	return 1.02
}

SCW_DestroyAllClipWins()
{
	MaxGuis := SCW_Reg("MaxGuis"), StartAfter := SCW_Reg("StartAfter")
	Loop, %MaxGuis%
	{
		StartAfter++
		Gui %StartAfter%: Destroy
	}
}

SCW_SetUp(Options="")
{
   if !(Options = "")
	{
		Loop, Parse, Options, %A_Space%
		{
			Field := A_LoopField
			DotPos := InStr(Field, ".")
			if (DotPos = 0)   
				Continue
			var := SubStr(Field, 1, DotPos-1)
			val := SubStr(Field, DotPos+1)
			if var in StartAfter,MaxGuis,AutoMonitorWM_LBUTTONDOWN,DrawCloseButton,BorderAColor,BorderBColor,SelColor,SelTrans
				%var% := val
		}
	}

	SCW_Default(StartAfter,80), SCW_Default(MaxGuis,6)
	SCW_Default(AutoMonitorWM_LBUTTONDOWN,1), SCW_Default(DrawCloseButton,0)
	SCW_Default(BorderAColor,"ff6666ff"), SCW_Default(BorderBColor,"ffffffff")
	SCW_Default(SelColor,"Yellow"), SCW_Default(SelTrans,80)
	SCW_Reg("MaxGuis", MaxGuis), SCW_Reg("StartAfter", StartAfter), SCW_Reg("DrawCloseButton", DrawCloseButton)
	SCW_Reg("BorderAColor", BorderAColor), SCW_Reg("BorderBColor", BorderBColor)
	SCW_Reg("SelColor", SelColor), SCW_Reg("SelTrans",SelTrans)
	SCW_Reg("WasSetUp", 1)
	if AutoMonitorWM_LBUTTONDOWN
		OnMessage(0x201, "SCW_LBUTTONDOWN")
}

SCW_ScreenClip2Win(SetClipboard:=0) 
{
	static c
	if !(SCW_Reg("WasSetUp"))
		SCW_SetUp()
	StartAfter := SCW_Reg("StartAfter"), MaxGuis := SCW_Reg("MaxGuis"), SelColor := SCW_Reg("SelColor"), SelTrans := SCW_Reg("SelTrans")
	c++
	if (c > MaxGuis)
		c := 1
	GuiNum := StartAfter + c
	Area := SCW_SelectAreaMod("g" GuiNum " c" SelColor " t" SelTrans)
	StringSplit, v, Area, |
	if (v3 < 10 and v4 < 10)   ; too small area
		return
	pToken := Gdip_Startup()
	if pToken =
	{
		MsgBox, 64, GDI+ error, GDI+ failed to start. Please ensure you have GDI+ on your system.
		return
	}
	Sleep, 100
	pBitmap := Gdip_BitmapFromScreen(Area)
	if (SetClipboard=1)
		Gdip_SetBitmapToClipboard(pBitmap)
	hwnd := SCW_CreateLayeredWinMod(GuiNum,pBitmap,v1,v2, SCW_Reg("DrawCloseButton"))
	Gdip_DisposeImage(pBitmap)
	Gdip_Shutdown("pToken")
	return hwnd
}

SCW_SelectAreaMod(Options="")
{
	CoordMode, Mouse, Screen
	MouseGetPos, MX, MY
	loop, parse, Options, %A_Space%
	{
		Field := A_LoopField
		FirstChar := SubStr(Field,1,1)
		if FirstChar contains c,t,g,m
		{
			StringTrimLeft, Field, Field, 1
			%FirstChar% := Field
		}
	}
	c := (c = "") ? "Blue" : c, t := (t = "") ? "50" : t, g := (g = "") ? "99" : g
	Gui %g%: Destroy
	Gui %g%: +AlwaysOnTop -caption +Border +ToolWindow +LastFound
	WinSet, Transparent, %t%
	Gui %g%: Color, %c%
	Hotkey := RegExReplace(A_ThisHotkey,"^(\w* & |\W*)")
	While, (GetKeyState(Hotkey, "p"))
	{
		Sleep, 10
		MouseGetPos, MXend, MYend
		w := abs(MX - MXend), h := abs(MY - MYend)
		X := (MX < MXend) ? MX : MXend
		Y := (MY < MYend) ? MY : MYend
		Gui %g%: Show, x%X% y%Y% w%w% h%h% NA
	}
	Gui %g%: Destroy
	MouseGetPos, MXend, MYend
	If ( MX > MXend )
		temp := MX, MX := MXend, MXend := temp
	If ( MY > MYend )
		temp := MY, MY := MYend, MYend := temp
	Return MX "|" MY "|" w "|" h
}

SCW_CreateLayeredWinMod(GuiNum,pBitmap,x,y,DrawCloseButton=0)
{
	static CloseButton := 16
	BorderAColor := SCW_Reg("BorderAColor"), BorderBColor := SCW_Reg("BorderBColor")

	Gui %GuiNum%: -Caption +E0x80000 +LastFound +ToolWindow +AlwaysOnTop +OwnDialogs
	Gui %GuiNum%: Show, Na, ScreenClipperWindow
	hwnd := WinExist()

	Width := Gdip_GetImageWidth(pBitmap), Height := Gdip_GetImageHeight(pBitmap)
	hbm := CreateDIBSection(Width+6, Height+6), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)
	G := Gdip_GraphicsFromHDC(hdc), Gdip_SetSmoothingMode(G, 4), Gdip_SetInterpolationMode(G, 7)

	Gdip_DrawImage(G, pBitmap, 3, 3, Width, Height)
	Gdip_DisposeImage(pBitmap)

	pPen1 := Gdip_CreatePen("0x" BorderAColor, 3), pPen2 := Gdip_CreatePen("0x" BorderBColor, 1)
	if DrawCloseButton
	{
		Gdip_DrawRectangle(G, pPen1, 1+Width-CloseButton+3, 1, CloseButton, CloseButton)
		Gdip_DrawRectangle(G, pPen2, 1+Width-CloseButton+3, 1, CloseButton, CloseButton)
	}
	Gdip_DrawRectangle(G, pPen1, 1, 1, Width+3, Height+3)
	Gdip_DrawRectangle(G, pPen2, 1, 1, Width+3, Height+3)
	Gdip_DeletePen(pPen1), Gdip_DeletePen(pPen2)

	UpdateLayeredWindow(hwnd, hdc, x-3, y-3, Width+6, Height+6)
	SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc), Gdip_DeleteGraphics(G)
	SCW_Reg("G" GuiNum "#HWND", hwnd)
	SCW_Reg("G" GuiNum "#XClose", Width+6-CloseButton)
	SCW_Reg("G" GuiNum "#YClose", CloseButton)
	Return hwnd
}

SCW_LBUTTONDOWN()
{
	MouseGetPos,,, WinUMID
	WinGetTitle, Title, ahk_id %WinUMID%
	if Title = ScreenClipperWindow
	{
		PostMessage, 0xA1, 2,,, ahk_id %WinUMID%
		KeyWait, Lbutton
		CoordMode, mouse, Relative
		MouseGetPos, x,y
		XClose := SCW_Reg("G" A_Gui "#XClose"), YClose := SCW_Reg("G" A_Gui "#YClose")
		if (x > XClose and y < YClose)
			Gui %A_Gui%: Destroy
		return 1   ; confirm that click was on module's screen clipping windows
	}
}

SCW_Reg(variable, value="")
{
	static
	if (value = "")
		return kxucfp%variable%pqzmdk
	else
		kxucfp%variable%pqzmdk = %value%
}

SCW_Default(ByRef Variable,DefaultValue)
{
	if (Variable="")
		Variable := DefaultValue
}

SCW_Win2Clipboard(DeleteBorders:=1, Hwnd := "")
{
	/*   ;   does not work for layered windows
	ActiveWinID := WinExist("A")
	pBitmap := Gdip_BitmapFromHWND(ActiveWinID)
	Gdip_SetBitmapToClipboard(pBitmap)
	*/
	if !Hwnd
		WinGet, Hwnd, ID, A
	WinGetPos, X, Y, W, H,  ahk_id %Hwnd%
	if DeleteBorders
		X+=3, Y+=3, W-=6, H-=6
	pToken := Gdip_Startup()
	pBitmap := Gdip_BitmapFromScreen(X "|" Y "|" W "|" H)
	Gdip_SetBitmapToClipboard(pBitmap)
	Gdip_Shutdown("pToken")
}

SCW_Win2File(DeleteBorders:=1, Hwnd := "", SavePath := ".\Images - Screen Clipper\") 
{
	RelativePath(SavePath)
	IfNotExist, %SavePath%
		FileCreateDir, %SavePath%
	if !Hwnd
		WinGet, Hwnd, ID, A
	WinGetPos, X, Y, W, H,  ahk_id %Hwnd%
	if DeleteBorders
		X+=3, Y+=3, W-=6, H-=6
	pToken := Gdip_Startup()
	pBitmap := Gdip_BitmapFromScreen(X "|" Y "|" W "|" H)
	FormatTime, TimeStamp ,, yyyy_MM_dd @ HH_mm_ss 
	FileName := TimeStamp " (" w "x" h  ").PNG"
	Gdip_SaveBitmapToFile(pBitmap, SavePath FileName)
	Gdip_DisposeImage(pBitmap)
	Gdip_Shutdown("pToken")
	return SavePath FileName
}
;}^^^^^ SCW Functions ^^^^^

Email_AttachFile(File, URL:="")
{
	try
		IsObject(MailItem := ComObjActive("Outlook.Application").CreateItem(olMailItem:=0)) ; Get the Outlook application object if Outlook is open
	catch
		MailItem  := ComObjCreate("Outlook.Application").CreateItem(olMailItem:=0) ; Create if Outlook is not open
	MailItem.BodyFormat := (olFormatHTML:=2)
	;~ MailItem.TO :="[email protected]"
	;~ MailItem.CC :="[email protected]"
	FormatTime, TimeStamp , % RegExReplace(File, "^.*\\|[_ @]|\(.*$"), dddd MMMM d, yyyy h:mm:ss tt
	MailItem.Subject :="Screen shot taken : " (TimeStamp) ; Subject line of email
	HTMLBody := "
		<H2 style='BACKGROUND-COLOR: red'><br></H2> 
		<HTML>Please find attached the screenshot taken on " TimeStamp "<br><br>"
	if URL
		HTMLBody .= "
			<span style='color:black'>The image can also be accessd here: <a href=""" (URL) """>" (URL) "</a>  <br><br></span>"
	HTMLBody .= "</HTML>"
	MailItem.HTMLBody := HTMLBody
	MailItem.Attachments.Add(File)
	MailItem.Display 
}

Imgur_Post(File, Client)
{
	Http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	Img := ComObjCreate("WIA.ImageFile")
	Img.LoadFile(File)
	/* 	; Converts Image to JPG
	IP := ComObjCreate("WIA.ImageProcess")
	IP.Filters.Add(IP.FilterInfos("Crop").FilterID)
	IP.Filters.Add(IP.FilterInfos("Convert").FilterID)
	IP.Filters(2).Properties("FormatID").Value:="{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"
	IP.Filters(2).Properties("Quality").Value:=85
	Img := IP.Apply(Img)
	*/
	Data := Img.FileData.BinaryData
	Http.Open("POST","https://api.imgur.com/3/upload")
	Http.SetRequestHeader("Authorization","Client-ID " Client)
	Http.SetRequestHeader("Content-Length",size)
	Http.Send(Data)
	Codes:=Http.ResponseText
	split=":"
	RegExMatch(Codes, "U)link" split "(.*)" Chr(34), Match)
	URL:=RegExReplace(Match1, "\\")
	Return URL
}

RelativePath(ByRef Path)
{
	RegExMatch(Path,"^(\.*)\\",M), R := StrLen(M1)
	if (R=1) 
		Path := A_ScriptDir SubStr(Path,R+1)
	else if (R>1)
		Path := SubStr(A_ScriptDir,1,InStr(A_ScriptDir,"\",,0,R-1)) SubStr(Path,R+2)
	return Path
}

GuiDefaultFont() { ; by SKAN (modified by just me)
   VarSetCapacity(LF, szLF := 28 + (A_IsUnicode ? 64 : 32), 0) ; LOGFONT structure
   If DllCall("GetObject", "Ptr", DllCall("GetStockObject", "Int", 17, "Ptr"), "Int", szLF, "Ptr", &LF)
      Return {Name: StrGet(&LF + 28, 32), Size: Round(Abs(NumGet(LF, 0, "Int")) * (72 / A_ScreenDPI), 1)
            , Weight: NumGet(LF, 16, "Int"), Quality: NumGet(LF, 26, "UChar")}
   Return False
}

;{ GuiButtonIcon
; Fanatic Guru
; 2014 05 31
; Version 2.0
;
; FUNCTION to Assign an Icon to a Gui Button
;
;------------------------------------------------
;
; Method:
;   GuiButtonIcon(Handle, File, Options)
;
;   Parameters:
;   1) {Handle} 	HWND handle of Gui button
;   2) {File} 		File containing icon image
;   3) {Index} 		Index of icon in file
;						Optional: Default = 1
;   4) {Options}	Single letter flag followed by a number with multiple options delimited by a space
;						W = Width of Icon (default = 16)
;						H = Height of Icon (default = 16)
;						S = Size of Icon, Makes Width and Height both equal to Size
;						L = Left Margin
;						T = Top Margin
;						R = Right Margin
;						B = Botton Margin
;						A = Alignment (0 = left, 1 = right, 2 = top, 3 = bottom, 4 = center; default = 4)
;
; Return:
;   1 = icon found, 0 = icon not found
;
; Example:
; Gui, Add, Button, w70 h38 hwndIcon, Save
; GuiButtonIcon(Icon, "shell32.dll", 259, "s30 a1 r2")
; Gui, Show
;
GuiButtonIcon(Handle, File, Index := 1, Options := "")
{
	RegExMatch(Options, "i)w\K\d+", W), (W="") ? W := 16 :
	RegExMatch(Options, "i)h\K\d+", H), (H="") ? H := 16 :
	RegExMatch(Options, "i)s\K\d+", S), S ? W := H := S :
	RegExMatch(Options, "i)l\K\d+", L), (L="") ? L := 0 :
	RegExMatch(Options, "i)t\K\d+", T), (T="") ? T := 0 :
	RegExMatch(Options, "i)r\K\d+", R), (R="") ? R := 0 :
	RegExMatch(Options, "i)b\K\d+", B), (B="") ? B := 0 :
	RegExMatch(Options, "i)a\K\d+", A), (A="") ? A := 4 :
	Psz := A_PtrSize = "" ? 4 : A_PtrSize, DW := "UInt", Ptr := A_PtrSize = "" ? DW : "Ptr"
	VarSetCapacity( button_il, 20 + Psz, 0 )
	NumPut( normal_il := DllCall( "ImageList_Create", DW, W, DW, H, DW, 0x21, DW, 1, DW, 1 ), button_il, 0, Ptr )	; Width & Height
	NumPut( L, button_il, 0 + Psz, DW )		; Left Margin
	NumPut( T, button_il, 4 + Psz, DW )		; Top Margin
	NumPut( R, button_il, 8 + Psz, DW )		; Right Margin
	NumPut( B, button_il, 12 + Psz, DW )	; Bottom Margin	
	NumPut( A, button_il, 16 + Psz, DW )	; Alignment
	SendMessage, BCM_SETIMAGELIST := 5634, 0, &button_il,, AHK_ID %Handle%
	return IL_Add( normal_il, File, Index )
}
This code requires the Gdip library. The Gdip_All.ahk as that is the most up-to-date but it has to be named Gdip.ahk in your library.

FG
Last edited by FanaticGuru on 26 May 2017, 23:07, edited 1 time in total.
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
fenchai
Posts: 292
Joined: 28 Mar 2016, 07:57

Re: Screenshooting tool

26 May 2017, 16:18

FanaticGuru wrote:Below is a screen clipping script that I use that also allows automatic uploading to Imgur.

There is a Help if you right click on the tray icon. Also you can right click on a clipping and use a context menu to do things with a clip.

Basic usage is just hold Window key and left mouse drag.

There is a function called Imgur_Post that could easily be used in any script to upload images anonymously to Imgur. You have to get a client token to upload. The code for uploading to a specific account is not included. I believe I know how to code this but never went to the trouble to implement it as it requires a client secret token that is only good for 30 days then you have to go through a process to get another one. To be useful I would have to automate the process for getting this secret token which seemed like too much trouble.

I also intended to have some type of cropping of a screen clip or restricting a screen clip to a certain size or ratio but again never got around to it.

Code: Select all

; Screen Clipper
; Fanatic Guru
; 2017 02 25
; Version 1.00
;
; Use Mouse Drag to Clip Selection of Screen
;
;{-----------------------------------------------
;
; Credits:
;
; Learning one	:=Screen Clipping
;		https://autohotkey.com/boards/viewtopic.php?f=6&t=12088
; Joe Glines		:= added Clip, IMGUR, Email parameters to ScreenClip2Win()
; maestrith		:= IMGUR upload
;		https://autohotkey.com/board/topic/95521-ahk-11-upload-a-screen-capture-to-imgur/
; tervon 			:= closing of clip window
;
;}

; INITIALIZATION - ENVIROMENT
;{-----------------------------------------------
;
#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  ; Ensures that only the last executed instance of script is running
;}

; INITIALIZATION - VARIABLES
;{-----------------------------------------------
;
 ;Obtain IMGUR API token value here: https://imgur.com/account/settings
Settings_Imgur_Client := "xxxxxxxxxxxxxx" ; Add client token here
Settings_SavePath := ".\Images - Screen Clipper\"
RelativePath(Settings_SavePath)
Settings_Ini := A_ScriptFullPath ": Screen Clipper.ini" ; Ini File in Script's Alternate Data Stream (requires NTFS)
Settings_Ini := A_ScriptDir "\Screen Clipper.ini" ; Normal Ini File

; Read Settings from Ini File
if FileExist(Settings_Ini)
{
	IniRead, Settings_Imgur_Client, %Settings_Ini%, Settings, Settings_Imgur_Client, %Settings_Imgur_Client%
	IniRead, Settings_SavePath, %Settings_Ini%, Settings, Settings_SavePath, %Settings_SavePath%
}

; Read Hotkeys from Script File
FileRead, Script, %A_ScriptFullPath%
Script :=  RegExReplace(Script, "ms`a)^\s*/\*.*?^\s*\*/\s*|^\s*\(.*?^\s*\)\s*")
Hotkeys := {}
Loop, Parse, Script, `n, `r
	if RegExMatch(A_LoopField,"^\s*(.*):`:.*`;\s*(.*)",Match)
	{
		if !RegExMatch(Match1,"(Shift|Alt|Ctrl|Win)")
		{
			StringReplace, Match1, Match1, +, Shift+
			StringReplace, Match1, Match1, <^>!, AltGr+
			StringReplace, Match1, Match1, <, Left, All
			StringReplace, Match1, Match1, >, Right, All 
			StringReplace, Match1, Match1, !, Alt+
			StringReplace, Match1, Match1, ^, Ctrl+
			StringReplace, Match1, Match1, #, Win+
		}
		Hotkeys.Push({"Hotkey":Match1, "Comment":Match2})
	}

;}

; INITIALIZATION - GUI
;{-----------------------------------------------
;
Menu, tray, icon, %A_WinDir%\system32\mmcndmgr.dll,106
;******************Tray Menu items***********
Menu, Tray, NoStandard ;removes default options
Menu, Tray, Add , Help, Help ;can doubleclick main
Menu, Tray, Default, Help ;sets to default
Menu, Tray, Add, Settings
Menu, Tray, Add, 
Menu, Tray, Add, Suspend
Menu, Tray, Add, Reload
Menu, Tray, Add, Edit
Menu, Tray, Add, Exit

Gui, +AlwaysOnTop +resize
Gui, Help:Default
Gui, Color, aqua
for Index, Element in Hotkeys
{
	Gui, Font, Bold
	Loop, Parse, % Element.Hotkey, +
	{
		If  (A_LoopField = "Win")
		{
			Gui, Font, cBlue
			xx := 40
		}
		else if (A_LoopField = "Alt")
		{
			Gui, Font, cRed
			xx := 75
		}
		else if (A_LoopField = "Ctrl")
		{
			Gui, Font, cGreen
			xx := 110
		}
		else if (A_LoopField = "Shift")
		{
			Gui, Font, cYellow
			xx := 5
		}
		else
		{
			Gui, Font, Bold cBlack
			xx := 145
		}
		if (A_Index = 1)
			Gui, Add, Text, x%xx% , % Format("{:Ts}", A_LoopField)
		else
			Gui, Add, Text, x%xx% yp , % Format("{:Ts}", A_LoopField)
	}
	Gui, Font
	Gui, Add, Text, yp x200, % Element.Comment
}

Gui, Settings:Default
Gui, Font, s10 bold
Gui, Add, Text, , Enter Path to Save Clips:
Gui, Font
Gui, Add, Edit, w500 vSettings_SavePath, %Settings_SavePath%
Gui, Add, Button, gSettings_ButtonPath yp x510 w22 h22 hwndIcon
GuiButtonIcon(Icon, "shell32.dll", 46, "s20")
Gui, Add, Text, x8, Starting ".\" indicates to start Relative Path in current folder.
Gui, Add, Text, yp+15,   Each additional "." indicates to start Relative Path up one folder
Gui, Add, Text, yp+15,   Example:  .\Images         (will store images in a subfolder of the working folder named "Images" )
Gui, Font, bold
Gui, Add, Text, yp+40, Enter Imgur Client ID:
Gui, Font
Gui, Add, Edit, yp-4 x140 w125 vSettings_Imgur_Client, %Settings_Imgur_Client%
Gui, Add, Button, yp+50 x100 w120 gSettings_ButtonSave, SAVE Settings
Gui, Add, Button, yp x300 w120 gSettings_ButtonUse Default, USE Settings

Menu, Context_Clip, add, COPY:  Clipboard, Context_Clip_Handler
Menu, Context_Clip, add, COPY:  Clipboard with Border, Context_Clip_Handler
Menu, Context_Clip, add, COPY:  File, Context_Clip_Handler
Menu, Context_Clip, add, COPY:  File with Border, Context_Clip_Handler
Menu, Context_Clip, add, COPY:  File && Email, Context_Clip_Handler
Menu, Context_Clip, add, COPY:  File && Imgur, Context_Clip_Handler
Menu, Context_Clip, add, COPY:  File`, Imgur && Email, Context_Clip_Handler
Menu, Context_Clip, add
Menu, Context_Clip, add, CLOSE:  Clip Image, Context_Clip_Handler

;}

; BEGINNING OF AUTO-EXECUTE
;{-----------------------------------------------
;

;
;}-----------------------------------------------
; END OF AUTO-EXECUTE

; HOTKEYS
;{-----------------------------------------------
;
#Lbutton::		;	<-- Clip Image Only
	SCW_ScreenClip2Win(SetClipboard:=false)
return

#^Lbutton::	;	<-- Clip Image and Copy to Clipboard
	SCW_ScreenClip2Win(SetClipboard:=true)
return

#!Lbutton::		;	<-- Clip Image and Save to File
	Hwnd := SCW_ScreenClip2Win(SetClipboard:=false)
	MsgBox % Settings_SavePath
	SCW_Win2File(,Hwnd)
return

#^!Lbutton::	;	<-- Clip Image, Copy to Clipboard, and Save to File
	Hwnd := SCW_ScreenClip2Win(SetClipboard:=true)
	SCW_Win2File(,Hwnd)
return

#IfWinActive, ScreenClipperWindow ahk_class AutoHotkeyGUI
	^c::				;	<-- (Screen Clipper) : Copy Active Clip to Clipboard
		SCW_Win2Clipboard()
	return
	+^c::			;	<-- (Screen Clipper) : Copy Active Clip to Clipboard with Border
		SCW_Win2Clipboard(0)
	return
	^s::				;	<-- (Screen Clipper) : Save Active Clip to File
		SCW_Win2File()
	return
	+^s::			;	<-- (Screen Clipper) : Save Active Clip to File with Border
		SCW_Win2File(,0)
	return
	#e::				;	<-- (Screen Clipper) : Save Active Clip to File and Email
		File := SCW_Win2File()
		Email_AttachFile(File)
	return
	#i::				;	<-- (Screen Clipper) : Save Active Clip to File and Post to IMGUR
		File := SCW_Win2File()
		URL := Imgur_Post(File, Settings_Imgur_Client)
		Clipboard := URL
	return
	#^i::				;	<-- (Screen Clipper) : Save Active Clip to File, Post to IMGUR and Email
		File := SCW_Win2File()
		URL := Imgur_Post(File, Settings_Imgur_Client)
		Email_AttachFile(File, URL)
	return
	RButton::	;	<-- (Screen Clipper) : Single for Menu, Double to Close Active Clip
		KeyWait, RButton			; wait release
		KeyWait, RButton, D T0.2	; and pressed again within 0.2 seconds
		if ErrorLevel ; timed-out (only a single press)
			Menu, Context_Clip, Show
		else
			WinClose, A
	return
	Esc::				;	<-- (Screen Clipper) : Close Active Clip
		WinClose, A
	return
#IfWinActive
;}

; SUBROUTINES
;{-----------------------------------------------
;

;}

; SUBROUTINES - GUI
;{-----------------------------------------------
;
Settings_ButtonPath:
	FileSelectFolder, Settings_SavePath, *%Settings_SavePath%, 3, Select Folder for Saved Image
	GuiControl, Settings:, Settings_SavePath, %Settings_SavePath%\
return
Settings_ButtonUSE:
	Gui, Settings:Submit
return
Settings_ButtonSAVE:
	Gui, Settings:Submit
	IniWrite, %Settings_Imgur_Client%, %Settings_Ini%, Settings, Settings_Imgur_Client
	IniWrite, %Settings_SavePath%, %Settings_Ini%, Settings, Settings_SavePath
return
HelpGuiEscape:
HelpGuiClose:
	Gui, Help:Hide
Return

;~ Context Menu for Clip Window
Context_Clip_Handler:
		if (A_ThisMenuItemPos = 9) ; Close Clip Image
			WinClose, A
		Sleep 350	; Context Menu selection fades out and needs time to disappear before Clipping
		if  (A_ThisMenuItemPos = 1)		; Clipboard
			SCW_Win2Clipboard()
		else if (A_ThisMenuItemPos = 2)	; Clipboard with Border
			SCW_Win2Clipboard(0)
		else if (A_ThisMenuItemPos = 3) ; File
			SCW_Win2File()
		else if (A_ThisMenuItemPos = 4) ; File with Border
			SCW_Win2File(,0)
		else if (A_ThisMenuItemPos = 5) ; File & Email
		{
			File := SCW_Win2File()
			Email_AttachFile(File)
		}
		else if (A_ThisMenuItemPos = 6) ; File & Imgur
		{
			File := SCW_Win2File()
			URL := Imgur_Post(File, Settings_Imgur_Client)
			Clipboard := URL
		}
		else if (A_ThisMenuItemPos = 7) ; File, Imgur & Email
		{
			File := SCW_Win2File()
			URL := Imgur_Post(File, Settings_Imgur_Client)
			Email_AttachFile(File, URL)
		}
		
	;~ MsgBox You selected %A_ThisMenuItemPos% - %A_ThisMenuItem% from the menu %A_ThisMenu%.
return

;~ Tray Menu
Help:
	Gui,Help:Show, , Help
return
Settings:
	Gui,Settings:Show, , Settings
return
Suspend:
	Suspend
Return
Reload:
	Reload
Return
Edit:
	Edit
Return
Exit:
	ExitApp
Return
;}

; FUNCTIONS
;{-----------------------------------------------
;
;{vvvvv SCW Functions vvvvv
/*
[module/script] ScreenClip2Win
Author:      Learning one
Thanks:      Tic, HotKeyIt

Creates always on top layered windows from screen clippings. Click in upper right corner to close win. Click and drag to move it.
Uses Gdip.ahk by Tic.

#Include ScreenClip2Win.ahk    						; by Learning one
;=== Short documentation ===
SCW_ScreenClip2Win(SetClipboard:=0) 		; creates always on top window from screen clipping. Click and drag to select area.
SCW_DestroyAllClipWins()								; destroys all screen clipping windows.
SCW_Win2Clipboard(DeleteBorders:=1)			; copies window to clipboard. By default, removes borders. To keep borders, specify "SCW_Win2Clipboard(0)"
SCW_SetUp(Options="")		; you can change some default options in Auto-execute part of script. Syntax: "<option>.<value>"
	StartAfter - module will start to consume GUIs for screen clipping windows after specified GUI number. Default: 80
	MaxGuis - maximum number of screen clipping windows. Default: 6
	BorderAColor - Default: ff6666ff (ARGB format)
	BorderBColor - Default: ffffffff (ARGB format)
	DrawCloseButton - on/off draw "Close Button" on screen clipping windows. Default: 0 (off)
	AutoMonitorWM_LBUTTONDOWN - on/off automatic monitoring of WM_LBUTTONDOWN message. Default: 1 (on)
	SelColor - selection color. Default: Yellow
	SelTrans - selection transparency. Default: 80

	Example:   SCW_SetUp("MaxGuis.30 StartAfter.50 BorderAColor.ff000000 BorderBColor.ffffff00")

;=== Avoid OnMessage(0x201, "WM_LBUTTONDOWN") collision example===
Gui, Show, w200 h200
SCW_SetUp("AutoMonitorWM_LBUTTONDOWN.0")   ; turn off auto monitoring WM_LBUTTONDOWN
OnMessage(0x201, "WM_LBUTTONDOWN")   ; manualy monitor WM_LBUTTONDOWN
Return

^Lbutton::SCW_ScreenClip2Win()   ; click & drag
Esc::ExitApp

#Include Gdip.ahk      ; by Tic
#Include ScreenClip2Win.ahk      ; by Learning one
WM_LBUTTONDOWN() {
	if SCW_LBUTTONDOWN()   ; LBUTTONDOWN on module's screen clipping windows - isolate - it's module's buissines
		return
	else   ; LBUTTONDOWN on other windows created by script
		MsgBox,,, You clicked on script's window not created by this module,1
}
*/

SCW_Version()
{
	return 1.02
}

SCW_DestroyAllClipWins()
{
	MaxGuis := SCW_Reg("MaxGuis"), StartAfter := SCW_Reg("StartAfter")
	Loop, %MaxGuis%
	{
		StartAfter++
		Gui %StartAfter%: Destroy
	}
}

SCW_SetUp(Options="")
{
   if !(Options = "")
	{
		Loop, Parse, Options, %A_Space%
		{
			Field := A_LoopField
			DotPos := InStr(Field, ".")
			if (DotPos = 0)   
				Continue
			var := SubStr(Field, 1, DotPos-1)
			val := SubStr(Field, DotPos+1)
			if var in StartAfter,MaxGuis,AutoMonitorWM_LBUTTONDOWN,DrawCloseButton,BorderAColor,BorderBColor,SelColor,SelTrans
				%var% := val
		}
	}

	SCW_Default(StartAfter,80), SCW_Default(MaxGuis,6)
	SCW_Default(AutoMonitorWM_LBUTTONDOWN,1), SCW_Default(DrawCloseButton,0)
	SCW_Default(BorderAColor,"ff6666ff"), SCW_Default(BorderBColor,"ffffffff")
	SCW_Default(SelColor,"Yellow"), SCW_Default(SelTrans,80)
	SCW_Reg("MaxGuis", MaxGuis), SCW_Reg("StartAfter", StartAfter), SCW_Reg("DrawCloseButton", DrawCloseButton)
	SCW_Reg("BorderAColor", BorderAColor), SCW_Reg("BorderBColor", BorderBColor)
	SCW_Reg("SelColor", SelColor), SCW_Reg("SelTrans",SelTrans)
	SCW_Reg("WasSetUp", 1)
	if AutoMonitorWM_LBUTTONDOWN
		OnMessage(0x201, "SCW_LBUTTONDOWN")
}

SCW_ScreenClip2Win(SetClipboard:=0) 
{
	static c
	if !(SCW_Reg("WasSetUp"))
		SCW_SetUp()
	StartAfter := SCW_Reg("StartAfter"), MaxGuis := SCW_Reg("MaxGuis"), SelColor := SCW_Reg("SelColor"), SelTrans := SCW_Reg("SelTrans")
	c++
	if (c > MaxGuis)
		c := 1
	GuiNum := StartAfter + c
	Area := SCW_SelectAreaMod("g" GuiNum " c" SelColor " t" SelTrans)
	StringSplit, v, Area, |
	if (v3 < 10 and v4 < 10)   ; too small area
		return
	pToken := Gdip_Startup()
	if pToken =
	{
		MsgBox, 64, GDI+ error, GDI+ failed to start. Please ensure you have GDI+ on your system.
		return
	}
	Sleep, 100
	pBitmap := Gdip_BitmapFromScreen(Area)
	if (SetClipboard=1)
		Gdip_SetBitmapToClipboard(pBitmap)
	hwnd := SCW_CreateLayeredWinMod(GuiNum,pBitmap,v1,v2, SCW_Reg("DrawCloseButton"))
	Gdip_DisposeImage(pBitmap)
	Gdip_Shutdown("pToken")
	return hwnd
}

SCW_SelectAreaMod(Options="")
{
	CoordMode, Mouse, Screen
	MouseGetPos, MX, MY
	loop, parse, Options, %A_Space%
	{
		Field := A_LoopField
		FirstChar := SubStr(Field,1,1)
		if FirstChar contains c,t,g,m
		{
			StringTrimLeft, Field, Field, 1
			%FirstChar% := Field
		}
	}
	c := (c = "") ? "Blue" : c, t := (t = "") ? "50" : t, g := (g = "") ? "99" : g
	Gui %g%: Destroy
	Gui %g%: +AlwaysOnTop -caption +Border +ToolWindow +LastFound
	WinSet, Transparent, %t%
	Gui %g%: Color, %c%
	Hotkey := RegExReplace(A_ThisHotkey,"^(\w* & |\W*)")
	While, (GetKeyState(Hotkey, "p"))
	{
		Sleep, 10
		MouseGetPos, MXend, MYend
		w := abs(MX - MXend), h := abs(MY - MYend)
		X := (MX < MXend) ? MX : MXend
		Y := (MY < MYend) ? MY : MYend
		Gui %g%: Show, x%X% y%Y% w%w% h%h% NA
	}
	Gui %g%: Destroy
	MouseGetPos, MXend, MYend
	If ( MX > MXend )
		temp := MX, MX := MXend, MXend := temp
	If ( MY > MYend )
		temp := MY, MY := MYend, MYend := temp
	Return MX "|" MY "|" w "|" h
}

SCW_CreateLayeredWinMod(GuiNum,pBitmap,x,y,DrawCloseButton=0)
{
	static CloseButton := 16
	BorderAColor := SCW_Reg("BorderAColor"), BorderBColor := SCW_Reg("BorderBColor")

	Gui %GuiNum%: -Caption +E0x80000 +LastFound +ToolWindow +AlwaysOnTop +OwnDialogs
	Gui %GuiNum%: Show, Na, ScreenClipperWindow
	hwnd := WinExist()

	Width := Gdip_GetImageWidth(pBitmap), Height := Gdip_GetImageHeight(pBitmap)
	hbm := CreateDIBSection(Width+6, Height+6), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)
	G := Gdip_GraphicsFromHDC(hdc), Gdip_SetSmoothingMode(G, 4), Gdip_SetInterpolationMode(G, 7)

	Gdip_DrawImage(G, pBitmap, 3, 3, Width, Height)
	Gdip_DisposeImage(pBitmap)

	pPen1 := Gdip_CreatePen("0x" BorderAColor, 3), pPen2 := Gdip_CreatePen("0x" BorderBColor, 1)
	if DrawCloseButton
	{
		Gdip_DrawRectangle(G, pPen1, 1+Width-CloseButton+3, 1, CloseButton, CloseButton)
		Gdip_DrawRectangle(G, pPen2, 1+Width-CloseButton+3, 1, CloseButton, CloseButton)
	}
	Gdip_DrawRectangle(G, pPen1, 1, 1, Width+3, Height+3)
	Gdip_DrawRectangle(G, pPen2, 1, 1, Width+3, Height+3)
	Gdip_DeletePen(pPen1), Gdip_DeletePen(pPen2)

	UpdateLayeredWindow(hwnd, hdc, x-3, y-3, Width+6, Height+6)
	SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc), Gdip_DeleteGraphics(G)
	SCW_Reg("G" GuiNum "#HWND", hwnd)
	SCW_Reg("G" GuiNum "#XClose", Width+6-CloseButton)
	SCW_Reg("G" GuiNum "#YClose", CloseButton)
	Return hwnd
}

SCW_LBUTTONDOWN()
{
	MouseGetPos,,, WinUMID
	WinGetTitle, Title, ahk_id %WinUMID%
	if Title = ScreenClipperWindow
	{
		PostMessage, 0xA1, 2,,, ahk_id %WinUMID%
		KeyWait, Lbutton
		CoordMode, mouse, Relative
		MouseGetPos, x,y
		XClose := SCW_Reg("G" A_Gui "#XClose"), YClose := SCW_Reg("G" A_Gui "#YClose")
		if (x > XClose and y < YClose)
			Gui %A_Gui%: Destroy
		return 1   ; confirm that click was on module's screen clipping windows
	}
}

SCW_Reg(variable, value="")
{
	static
	if (value = "")
		return kxucfp%variable%pqzmdk
	else
		kxucfp%variable%pqzmdk = %value%
}

SCW_Default(ByRef Variable,DefaultValue)
{
	if (Variable="")
		Variable := DefaultValue
}

SCW_Win2Clipboard(DeleteBorders:=1, Hwnd := "")
{
	/*   ;   does not work for layered windows
	ActiveWinID := WinExist("A")
	pBitmap := Gdip_BitmapFromHWND(ActiveWinID)
	Gdip_SetBitmapToClipboard(pBitmap)
	*/
	if !Hwnd
		WinGet, Hwnd, ID, A
	WinGetPos, X, Y, W, H,  ahk_id %Hwnd%
	if DeleteBorders
		X+=3, Y+=3, W-=6, H-=6
	pToken := Gdip_Startup()
	pBitmap := Gdip_BitmapFromScreen(X "|" Y "|" W "|" H)
	Gdip_SetBitmapToClipboard(pBitmap)
	Gdip_Shutdown("pToken")
}

SCW_Win2File(DeleteBorders:=1, Hwnd := "", SavePath := ".\Images - Screen Clipper\") 
{
	RelativePath(SavePath)
	IfNotExist, %SavePath%
		FileCreateDir, %SavePath%
	if !Hwnd
		WinGet, Hwnd, ID, A
	WinGetPos, X, Y, W, H,  ahk_id %Hwnd%
	if DeleteBorders
		X+=3, Y+=3, W-=6, H-=6
	pToken := Gdip_Startup()
	pBitmap := Gdip_BitmapFromScreen(X "|" Y "|" W "|" H)
	FormatTime, TimeStamp ,, yyyy_MM_dd @ HH_mm_ss 
	FileName := TimeStamp " (" w "x" h  ").PNG"
	Gdip_SaveBitmapToFile(pBitmap, SavePath FileName)
	Gdip_DisposeImage(pBitmap)
	Gdip_Shutdown("pToken")
	return SavePath FileName
}
;}^^^^^ SCW Functions ^^^^^

Email_AttachFile(File, URL:="")
{
	try
		IsObject(MailItem := ComObjActive("Outlook.Application").CreateItem(olMailItem:=0)) ; Get the Outlook application object if Outlook is open
	catch
		MailItem  := ComObjCreate("Outlook.Application").CreateItem(olMailItem:=0) ; Create if Outlook is not open
	MailItem.BodyFormat := (olFormatHTML:=2)
	;~ MailItem.TO :="[email protected]"
	;~ MailItem.CC :="[email protected]"
	FormatTime, TimeStamp , % RegExReplace(File, "^.*\\|[_ @]|\(.*$"), dddd MMMM d, yyyy h:mm:ss tt
	MailItem.Subject :="Screen shot taken : " (TimeStamp) ; Subject line of email
	HTMLBody := "
		<H2 style='BACKGROUND-COLOR: red'><br></H2> 
		<HTML>Please find attached the screenshot taken on " TimeStamp "<br><br>"
	if URL
		HTMLBody .= "
			<span style='color:black'>The image can also be accessd here: <a href=""" (URL) """>" (URL) "</a>  <br><br></span>"
	HTMLBody .= "</HTML>"
	MailItem.HTMLBody := HTMLBody
	MailItem.Attachments.Add(File)
	MailItem.Display 
}

Imgur_Post(File, Client)
{
	Http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	Img := ComObjCreate("WIA.ImageFile")
	Img.LoadFile(File)
	/* 	; Converts Image to JPG
	IP := ComObjCreate("WIA.ImageProcess")
	IP.Filters.Add(IP.FilterInfos("Crop").FilterID)
	IP.Filters.Add(IP.FilterInfos("Convert").FilterID)
	IP.Filters(2).Properties("FormatID").Value:="{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"
	IP.Filters(2).Properties("Quality").Value:=85
	Img := IP.Apply(Img)
	*/
	Data := Img.FileData.BinaryData
	Http.Open("POST","https://api.imgur.com/3/upload")
	Http.SetRequestHeader("Authorization","Client-ID " Client)
	Http.SetRequestHeader("Content-Length",size)
	Http.Send(Data)
	Codes:=Http.ResponseText
	split=":"
	RegExMatch(Codes, "U)link" split "(.*)" Chr(34), Match)
	URL:=RegExReplace(Match1, "\\")
	Return URL
}

RelativePath(ByRef Path)
{
	RegExMatch(Path,"^(\.*)\\",M), R := StrLen(M1)
	if (R=1) 
		Path := A_ScriptDir SubStr(Path,R+1)
	else if (R>1)
		Path := SubStr(A_ScriptDir,1,InStr(A_ScriptDir,"\",,0,R-1)) SubStr(Path,R+2)
	return Path
}

GuiDefaultFont() { ; by SKAN (modified by just me)
   VarSetCapacity(LF, szLF := 28 + (A_IsUnicode ? 64 : 32), 0) ; LOGFONT structure
   If DllCall("GetObject", "Ptr", DllCall("GetStockObject", "Int", 17, "Ptr"), "Int", szLF, "Ptr", &LF)
      Return {Name: StrGet(&LF + 28, 32), Size: Round(Abs(NumGet(LF, 0, "Int")) * (72 / A_ScreenDPI), 1)
            , Weight: NumGet(LF, 16, "Int"), Quality: NumGet(LF, 26, "UChar")}
   Return False
}
FG
ERROR

Specifically: GuiButtonIcon(Icon, "shell32.dll", 46, "s20")

Btw using WIN+LEFT CLICK DRAG is an awesome idea. I would like to check out your code. Why is uploading without an account so difficult? I would like to just upload the image directly since I know their servers now do not delete an image, I think they gave premium to all users or something like that.
fenchai
Posts: 292
Joined: 28 Mar 2016, 07:57

Re: Screenshooting tool

26 May 2017, 16:21

Run1e wrote:
fenchai wrote:for how long does it stay uploaded in their database? I googled and found its 6 months if no view then other thread said permanent unless deletion is requested.
You could log in to your account with OAuth2.0 through the API and the picture will stay forever. I decided not to do that for the public version Power Play because I'd have to handle sensitive data.
Can you extract the code for uploading to imgur? I have seen your program and it is amazing, but I do not use any of its features. (I have also tried to check the imgur upload function and got so lost...lol) I only want to be able to upload to imgur, better if It does not need an account.
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: Screenshooting tool

26 May 2017, 23:03

fenchai wrote:ERROR

Specifically: GuiButtonIcon(Icon, "shell32.dll", 46, "s20")

Btw using WIN+LEFT CLICK DRAG is an awesome idea. I would like to check out your code. Why is uploading without an account so difficult? I would like to just upload the image directly since I know their servers now do not delete an image, I think they gave premium to all users or something like that.
Sorry did not notice that it required a function in my library.

Code: Select all

;{ GuiButtonIcon
; Fanatic Guru
; 2014 05 31
; Version 2.0
;
; FUNCTION to Assign an Icon to a Gui Button
;
;------------------------------------------------
;
; Method:
;   GuiButtonIcon(Handle, File, Options)
;
;   Parameters:
;   1) {Handle} 	HWND handle of Gui button
;   2) {File} 		File containing icon image
;   3) {Index} 		Index of icon in file
;						Optional: Default = 1
;   4) {Options}	Single letter flag followed by a number with multiple options delimited by a space
;						W = Width of Icon (default = 16)
;						H = Height of Icon (default = 16)
;						S = Size of Icon, Makes Width and Height both equal to Size
;						L = Left Margin
;						T = Top Margin
;						R = Right Margin
;						B = Botton Margin
;						A = Alignment (0 = left, 1 = right, 2 = top, 3 = bottom, 4 = center; default = 4)
;
; Return:
;   1 = icon found, 0 = icon not found
;
; Example:
; Gui, Add, Button, w70 h38 hwndIcon, Save
; GuiButtonIcon(Icon, "shell32.dll", 259, "s30 a1 r2")
; Gui, Show
;
GuiButtonIcon(Handle, File, Index := 1, Options := "")
{
	RegExMatch(Options, "i)w\K\d+", W), (W="") ? W := 16 :
	RegExMatch(Options, "i)h\K\d+", H), (H="") ? H := 16 :
	RegExMatch(Options, "i)s\K\d+", S), S ? W := H := S :
	RegExMatch(Options, "i)l\K\d+", L), (L="") ? L := 0 :
	RegExMatch(Options, "i)t\K\d+", T), (T="") ? T := 0 :
	RegExMatch(Options, "i)r\K\d+", R), (R="") ? R := 0 :
	RegExMatch(Options, "i)b\K\d+", B), (B="") ? B := 0 :
	RegExMatch(Options, "i)a\K\d+", A), (A="") ? A := 4 :
	Psz := A_PtrSize = "" ? 4 : A_PtrSize, DW := "UInt", Ptr := A_PtrSize = "" ? DW : "Ptr"
	VarSetCapacity( button_il, 20 + Psz, 0 )
	NumPut( normal_il := DllCall( "ImageList_Create", DW, W, DW, H, DW, 0x21, DW, 1, DW, 1 ), button_il, 0, Ptr )	; Width & Height
	NumPut( L, button_il, 0 + Psz, DW )		; Left Margin
	NumPut( T, button_il, 4 + Psz, DW )		; Top Margin
	NumPut( R, button_il, 8 + Psz, DW )		; Right Margin
	NumPut( B, button_il, 12 + Psz, DW )	; Bottom Margin	
	NumPut( A, button_il, 16 + Psz, DW )	; Alignment
	SendMessage, BCM_SETIMAGELIST := 5634, 0, &button_il,, AHK_ID %Handle%
	return IL_Add( normal_il, File, Index )
}
You can put that code at the end of the script or add that file to your library.

To upload to Imgur requires a client token. I could give my client token to the whole forum and then everyone could upload images that are not added to any account. When I logged on to my account I would not be able to see the images in my library. They are basically anonymous uploads but they still require a client token to upload.

I assume if too many pictures get upload from any one client token the token gets suspended to prevent someone from just uploading terabytes of data 24 hours a day. It is not that hard to get a token that allows anonymous uploads but you do have to create an account to access the screens to do it. The token for anonymous uploads also never expires. It is a one time process.

Now if you want to actually upload pictures to your account, you have to get what they call a secret token which does expire every 30 days. I am not sure the reasoning behind making those expire. I guess they don't want secret tokens to get passed around for dormant forgotten accounts that lots of people then just start using as they basically have promised to not delete pictures from actually accounts but anonymous pictures can be deleted after 6 months of inactivity but from what I hear they do not actually do that but they could without warning at any point.

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
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: Screenshooting tool

26 May 2017, 23:14

fenchai wrote:Can you extract the code for uploading to imgur? I have seen your program and it is amazing, but I do not use any of its features. (I have also tried to check the imgur upload function and got so lost...lol) I only want to be able to upload to imgur, better if It does not need an account.
Uploading to Imgur can be done with a fairly small function:

Code: Select all

Imgur_Post(File, Client)
{
	Http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	Img := ComObjCreate("WIA.ImageFile")
	Img.LoadFile(File)
	Data := Img.FileData.BinaryData
	Http.Open("POST","https://api.imgur.com/3/upload")
	Http.SetRequestHeader("Authorization","Client-ID " Client)
	Http.SetRequestHeader("Content-Length",size)
	Http.Send(Data)
	Codes:=Http.ResponseText
	split=":"
	RegExMatch(Codes, "U)link" split "(.*)" Chr(34), Match)
	URL:=RegExReplace(Match1, "\\")
	Return URL
}
You just need to call the function with the path to the file to upload and a client token. The function will return the URL address for viewing the uploaded image.

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
fenchai
Posts: 292
Joined: 28 Mar 2016, 07:57

Re: Screenshooting tool

27 May 2017, 18:08

FanaticGuru wrote:
fenchai wrote:Can you extract the code for uploading to imgur? I have seen your program and it is amazing, but I do not use any of its features. (I have also tried to check the imgur upload function and got so lost...lol) I only want to be able to upload to imgur, better if It does not need an account.
Uploading to Imgur can be done with a fairly small function:

Code: Select all

Imgur_Post(File, Client)
{
	Http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	Img := ComObjCreate("WIA.ImageFile")
	Img.LoadFile(File)
	Data := Img.FileData.BinaryData
	Http.Open("POST","https://api.imgur.com/3/upload")
	Http.SetRequestHeader("Authorization","Client-ID " Client)
	Http.SetRequestHeader("Content-Length",size)
	Http.Send(Data)
	Codes:=Http.ResponseText
	split=":"
	RegExMatch(Codes, "U)link" split "(.*)" Chr(34), Match)
	URL:=RegExReplace(Match1, "\\")
	Return URL
}
You just need to call the function with the path to the file to upload and a client token. The function will return the URL address for viewing the uploaded image.

FG
Thank You :D

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 217 guests