vanheartnet

Screen Clipper

Aug 3rd, 2020
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.26 KB | None | 0 0
  1. ;Written By: Hellbent
  2. ;Date Started: Dec 6th, 2019
  3. ;Name: Screen Clipper.
  4. ;Inspired by the screen clipping tool by Joe Glines.
  5.  
  6. ;User Defined Values
  7. ;************************************************
  8. Hotkey, Ctrl , CreateCapWindow , On ;<------------------ Adjust the hotkey value to suit your needs / wants
  9. ;************************************************
  10. SaveToFile := 1 ;<------------------ Set this to 1 to save all clips with a unique name , Set it to 0 to overwrite the saved clip every time a new clip is made.
  11. ;************************************************
  12. ShowCloseButton := 1 ;<------------------ Set this to 1 to show a small close button in the top right corner of the clip. Set this to 0 to keep the close button, but not show it.
  13. ;************************************************
  14.  
  15. #SingleInstance, Force ; Force the script to close any other instances of this script. (Run one copy at a time)
  16. SetBatchLines, -1 ;Set the script to run at top speed.
  17. CoordMode, Mouse , Screen ;Use the screen as the refrence to get positions from.
  18.  
  19. IfNotExist, %A_ScriptDir%\Saved Clips ; if there is no folder for saved clips
  20. FileCreateDir, %A_ScriptDir%\Saved Clips ; create the folder.
  21. SetWorkingDir, %A_ScriptDir%\Saved Clips ;Set the saved clips folder as the working dir.
  22. Handles := [] ; Create an array to hold the name of the different gui's.
  23. Index := 0 ;Used as the name of the current gui cap window.
  24. return ; End of Auto-Execute Section.
  25.  
  26. ;**************************************************************************************
  27. ;**************************************************************************************
  28. ESC:: ExitApp ; Hotkey to exit the script.
  29. ;**************************************************************************************
  30. ;**************************************************************************************
  31.  
  32. CloseClip: ;Close (Destroy this gui)
  33. hwnd := WinActive() ;Get the handle to the active window
  34. Gui, % Handles[hwnd] ": Destroy" ;Destroy the gui with the name stored in the Handles array at position hwnd.
  35. return
  36.  
  37. MoveWindow:
  38. PostMessage, 0xA1 , 2 ;Move the active window
  39. return
  40.  
  41. CreateCapWindow: ;Create a gui to used for setting the screen cap area and to display the resulting screen shot.
  42. Index++ ;Increment the current index. (the gui's name)
  43. Gui, %Index% : New , +AlwaysOnTop -Caption -DPIScale +ToolWindow +LastFound +Border hwndHwnd ;Create a new gui and set its options.
  44. Handles[hwnd] := Index ;Use the windows handle (hwnd) as the index for the the value of the windows name.
  45. Gui, %Index% : Color , 123456 ;Set the color of the gui (This color will be made transparent in the next step)
  46. WinSet, TransColor , 123456 ;Set only this color as transparent
  47. Gui, %Index% : Font, cMaroon s10 Bold Q5 , Segoe UI ;Set this gui's font. (Used for the close button)
  48. Active := 1
  49. ToolTip, Click and drag to set capture area. ;Display a tooltip that tells the user what to do.
  50. SetTimer, Tooltips , 30 ;Set a timer to move the tooltip around with the users cursor.
  51. return
  52.  
  53. Tooltips:
  54. ToolTip, Click and drag to set capture area. ;Display a tooltip that tells the user what to do.
  55. return
  56.  
  57. DrawCapArea:
  58. if( !FirstPosition ){ ;If the first position hasn't been set yet.
  59. FirstPosition := 1 ;The first position is now set.
  60. MouseGetPos, SX , SY ;Get the x and y starting position.
  61. }else { ;After the first position is set.
  62. MouseGetPos, EX , EY ;Get the current position of the cursor.
  63. if( SX <= EX && SY <= EY ) ;If the current position is below and to the right of the starting position.
  64. WinPos := { X: SX , Y: SY , W: EX - SX , H: EY - SY } ;Create a object to hold the windows positions.
  65. else if( SX > EX && SY <= EY ) ;If the current position is below and to the left of the starting position.
  66. WinPos := { X: EX , Y: SY , W: SX - EX , H: EY - SY } ;Create a object to hold the windows positions.
  67. else if( SX <= EX && SY > EY) ;If the current position is above and to the right of the starting position.
  68. WinPos := { X: SX , Y: EY , W: EX - SX , H: SY - EY } ;Create a object to hold the windows positions.
  69. else if( SX > EX && SY > EY) ;If the current position is above and to the left of the starting position.
  70. WinPos := { X: EX , Y: EY , W: SX - EX , H: SY - EY } ;Create a object to hold the windows positions.
  71. }
  72. if( WinPos.W ) ;if the winpos object exists
  73. Gui, %Index% : Show , % "x" WinPos.X " y" WinPos.Y " w" WinPos.W " h" WinPos.H " NA" ;Show the window in the correct position.
  74. return
  75.  
  76. TakeScreenShot:
  77. pToken := Gdip_Startup() ;Start using Gdip
  78. ClipBitmap := Gdip_BitmapFromScreen( WinPos.X "|" WinPos.Y "|" WinPos.W "|" WinPos.H) ;Create a bitmap of the screen.
  79. Gdip_SaveBitmapToFile( ClipBitmap , A_WorkingDir "\" ( ( SaveToFile = 1 ) ? ( ClipName := "Saved Clip " A_Now ) : ( ClipName := "Temp Clip") ) ".png", 100 ) ; Save the bitmap to file
  80. Gdip_DisposeImage( ClipBitmap ) ;Dispose of the bitmap to free memory.
  81. Gdip_Shutdown(pToken) ;Turn off gdip
  82. return
  83.  
  84. #If (Active) ;Context sen Hotkeys.
  85.  
  86. LButton::
  87. WinPos := "" ;Clear this object.
  88. FirstPosition := 0 ;Variable used to determin if the starting point has been set yet.
  89. SetTimer, DrawCapArea , 30 ;Set a timer for drawing a rectangle around the capture area.
  90. return
  91.  
  92. LButton Up::
  93. Active := 0 ;Set context hotkeys off
  94. SetTimer, DrawCapArea , Off ;Turn off the drawing timer.
  95. SetTimer, Tooltips , Off ;Turn off the tooltips timer
  96. ToolTip, ;Turn off any tooltips.
  97. if( WinPos.W < 10 || WinPos.H < 10 ) { ; if the cap area width or height is less than 10px.
  98. Gui, %Index% : Destroy ;Destroy the gui
  99. return ; Skip taking a screen clip.
  100. }
  101. Gui, %Index% : -Border ;Remove the border before taking the screen clip
  102. gosub, TakeScreenShot ;Take a screen shot of the cap area.
  103. Gui, %Index% : +Border ;Add the border again.
  104.  
  105. Gui, %Index% : Add , Text , % ( ( ShowCloseButton ) ? ( " Center 0x200 Border " ) : ( "" ) ) " x" WinPos.W - 20 " y0 w20 h20 BackgroundTrans gCloseClip" , % ( ( ShowCloseButton ) ? ( "X" ) : ( "" ) ) ;Create a trigger used for closing this window.
  106. Gui, %Index% : Add , Text , % "x0 y0 w" WinPos.W " h" WinPos.H " BackgroundTrans gMoveWindow" ;Create a trigger used for moving the window around.
  107. Gui, %Index% : Add , Picture , % "x0 y0 w" WinPos.W " h" WinPos.H ,% ClipName ".png" ;Add the Screen clip image
  108. return
  109.  
  110. RButton:: ;If the right mouse button is pressed while selecting the screen clip area, Cancel the action and restore variables etc.
  111. Active := 0 ;Set context hotkeys off
  112. SetTimer, DrawCapArea , Off ;Turn off the drawing timer.
  113. SetTimer, Tooltips , Off ;Turn off the tooltips timer
  114. ToolTip, ;Turn off any tooltips.
  115. Gui, %Index% : Destroy ;Destroy the current gui
  116. return
  117.  
  118. #If
  119.  
  120. ;******************************************************************************************************************************************
  121. ;******************************************************************************************************************************************
  122. ;*************************************************** GDIP Functions *************************************************************
  123. ;******************************************************************************************************************************************
  124. ;******************************************************************************************************************************************
  125. Gdip_Startup(){
  126. Ptr := A_PtrSize ? "UPtr" : "UInt"
  127. if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
  128. DllCall("LoadLibrary", "str", "gdiplus")
  129. VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
  130. DllCall("gdiplus\GdiplusStartup", A_PtrSize ? "UPtr*" : "uint*", pToken, Ptr, &si, Ptr, 0)
  131. return pToken
  132. }
  133. Gdip_BitmapFromScreen(Screen=0, Raster=""){
  134. if (Screen = 0){
  135. Sysget, x, 76
  136. Sysget, y, 77
  137. Sysget, w, 78
  138. Sysget, h, 79
  139. }else if (SubStr(Screen, 1, 5) = "hwnd:"){
  140. Screen := SubStr(Screen, 6)
  141. if !WinExist( "ahk_id " Screen)
  142. return -2
  143. WinGetPos,,, w, h, ahk_id %Screen%
  144. x := y := 0
  145. hhdc := GetDCEx(Screen, 3)
  146. }else if (Screen&1 != ""){
  147. Sysget, M, Monitor, %Screen%
  148. x := MLeft, y := MTop, w := MRight-MLeft, h := MBottom-MTop
  149. }else {
  150. StringSplit, S, Screen, |
  151. x := S1, y := S2, w := S3, h := S4
  152. }
  153. if (x = "") || (y = "") || (w = "") || (h = "")
  154. return -1
  155. chdc := CreateCompatibleDC(), hbm := CreateDIBSection(w, h, chdc), obm := SelectObject(chdc, hbm), hhdc := hhdc ? hhdc : GetDC()
  156. BitBlt(chdc, 0, 0, w, h, hhdc, x, y, Raster)
  157. ReleaseDC(hhdc)
  158. pBitmap := Gdip_CreateBitmapFromHBITMAP(hbm)
  159. SelectObject(chdc, obm), DeleteObject(hbm), DeleteDC(hhdc), DeleteDC(chdc)
  160. return pBitmap
  161. }
  162. Gdip_SaveBitmapToFile(pBitmap, sOutput, Quality=75){
  163. Ptr := A_PtrSize ? "UPtr" : "UInt"
  164. SplitPath, sOutput,,, Extension
  165. if Extension not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
  166. return -1
  167. Extension := "." Extension
  168. DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize)
  169. VarSetCapacity(ci, nSize)
  170. DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci)
  171. if !(nCount && nSize)
  172. return -2
  173. If (A_IsUnicode){
  174. StrGet_Name := "StrGet"
  175. Loop, % nCount {
  176. sString := %StrGet_Name%(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
  177. if !InStr(sString, "*" Extension)
  178. continue
  179. pCodec := &ci+idx
  180. break
  181. }
  182. } else {
  183. Loop, % nCount {
  184. Location := NumGet(ci, 76*(A_Index-1)+44)
  185. nSize := DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "uint", 0, "int", 0, "uint", 0, "uint", 0)
  186. VarSetCapacity(sString, nSize)
  187. DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "str", sString, "int", nSize, "uint", 0, "uint", 0)
  188. if !InStr(sString, "*" Extension)
  189. continue
  190. pCodec := &ci+76*(A_Index-1)
  191. break
  192. }
  193. }
  194. if !pCodec
  195. return -3
  196. if (Quality != 75){
  197. Quality := (Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality
  198. if Extension in .JPG,.JPEG,.JPE,.JFIF
  199. {
  200. DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, "uint*", nSize)
  201. VarSetCapacity(EncoderParameters, nSize, 0)
  202. DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, Ptr, pCodec, "uint", nSize, Ptr, &EncoderParameters)
  203. Loop, % NumGet(EncoderParameters, "UInt") {
  204. elem := (24+(A_PtrSize ? A_PtrSize : 4))*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
  205. if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6){
  206. p := elem+&EncoderParameters-pad-4
  207. NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
  208. break
  209. }
  210. }
  211. }
  212. }
  213. if (!A_IsUnicode){
  214. nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sOutput, "int", -1, Ptr, 0, "int", 0)
  215. VarSetCapacity(wOutput, nSize*2)
  216. DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sOutput, "int", -1, Ptr, &wOutput, "int", nSize)
  217. VarSetCapacity(wOutput, -1)
  218. if !VarSetCapacity(wOutput)
  219. return -4
  220. E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, &wOutput, Ptr, pCodec, "uint", p ? p : 0)
  221. }
  222. else
  223. E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, &sOutput, Ptr, pCodec, "uint", p ? p : 0)
  224. return E ? -5 : 0
  225. }
  226. Gdip_DisposeImage(pBitmap){
  227. return DllCall("gdiplus\GdipDisposeImage", A_PtrSize ? "UPtr" : "UInt", pBitmap)
  228. }
  229. Gdip_Shutdown(pToken){
  230. Ptr := A_PtrSize ? "UPtr" : "UInt"
  231. DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
  232. if hModule := DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
  233. DllCall("FreeLibrary", Ptr, hModule)
  234. return 0
  235. }
  236. GetDCEx(hwnd, flags=0, hrgnClip=0){
  237. Ptr := A_PtrSize ? "UPtr" : "UInt"
  238. return DllCall("GetDCEx", Ptr, hwnd, Ptr, hrgnClip, "int", flags)
  239. }
  240. CreateCompatibleDC(hdc=0){
  241. return DllCall("CreateCompatibleDC", A_PtrSize ? "UPtr" : "UInt", hdc)
  242. }
  243. CreateDIBSection(w, h, hdc="", bpp=32, ByRef ppvBits=0){
  244. Ptr := A_PtrSize ? "UPtr" : "UInt"
  245. hdc2 := hdc ? hdc : GetDC()
  246. VarSetCapacity(bi, 40, 0)
  247. 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")
  248. hbm := DllCall("CreateDIBSection" , Ptr, hdc2 , Ptr, &bi , "uint", 0 , A_PtrSize ? "UPtr*" : "uint*", ppvBits , Ptr, 0 , "uint", 0, Ptr)
  249. if !hdc
  250. ReleaseDC(hdc2)
  251. return hbm
  252. }
  253. SelectObject(hdc, hgdiobj){
  254. Ptr := A_PtrSize ? "UPtr" : "UInt"
  255. return DllCall("SelectObject", Ptr, hdc, Ptr, hgdiobj)
  256. }
  257. GetDC(hwnd=0){
  258. return DllCall("GetDC", A_PtrSize ? "UPtr" : "UInt", hwnd)
  259. }
  260. BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster=""){
  261. Ptr := A_PtrSize ? "UPtr" : "UInt"
  262. return DllCall("gdi32\BitBlt" , Ptr, dDC , "int", dx , "int", dy , "int", dw , "int", dh , Ptr, sDC , "int", sx , "int", sy , "uint", Raster ? Raster : 0x00CC0020)
  263. }
  264. ReleaseDC(hdc, hwnd=0){
  265. Ptr := A_PtrSize ? "UPtr" : "UInt"
  266. return DllCall("ReleaseDC", Ptr, hwnd, Ptr, hdc)
  267. }
  268. Gdip_CreateBitmapFromHBITMAP(hBitmap, Palette=0){
  269. Ptr := A_PtrSize ? "UPtr" : "UInt"
  270. DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", Ptr, hBitmap, Ptr, Palette, A_PtrSize ? "UPtr*" : "uint*", pBitmap)
  271. return pBitmap
  272. }
  273. DeleteObject(hObject){
  274. return DllCall("DeleteObject", A_PtrSize ? "UPtr" : "UInt", hObject)
  275. }
  276. DeleteDC(hdc){
  277. return DllCall("DeleteDC", A_PtrSize ? "UPtr" : "UInt", hdc)
  278. }
Advertisement
Add Comment
Please, Sign In to add comment