AHK Screen Capture Tool

Post your working scripts, libraries and tools
feiyue
Posts: 162
Joined: 08 Aug 2014, 04:08

AHK Screen Capture Tool

20 Apr 2019, 05:06

Share a small tool to capture screen coordinates and colors. I hope you like it. :dance: :beer:

Code: Select all

;------------------------------
;  AHK Screen Capture Tool
;
;  Author: FeiYue
;  Version: 2.0
;  Introduction:
;  This is a convenient screen capture tool for coordinates and colors
;------------------------------
Goto, _Start

;======== Hotkey ========

;-- Press PrintScreen Hotkey to Capture Screen

*PrintScreen::
IfWinExist, ahk_id %gui_id%
{
  Gui, Main: Hide
  WinWaitClose, ahk_id %gui_id%
  Sleep, 50
}
hBM:=PrintScreen(nX, nY, nW, nH, bits)
SetImage(hPic2, hBM)
WinSet, ReDraw,, ahk_id %hPic2%
Gui, Main: Show
return

#If MouseIsOver()

MouseIsOver() {
  global hPic, gui_id
  ListLines, Off
  MouseGetPos, px, py, id, cid, 2
  if (cid=hPic)
    return, 1
  if (id!=gui_id)
    return, 0
  WinGetPos, x, y, w, h, ahk_id %hPic%
  return, px>=x && px<x+w && py>=y && py<y+h
}

;-- Directional keys can be used for fine-tuning when capturing

*Left::
*Right::
*Up::
*Down::
key:=SubStr(A_ThisLabel, 2)
if (!kk)
  kk:={ "Left":[-1,0], "Right":[1,0], "Up":[0,-1], "Down":[0,1] }
MouseMove, kk[key].1, kk[key].2,, R
return

;-- You can use ALT+[0-9] combination hotkeys to capture points

*!1::
*!2::
*!3::
*!4::
*!5::
*!6::
*!7::
*!8::
*!9::
*!0::
n:=RegExReplace(A_ThisLabel, "\D+")
MouseGetPos, px, py
Gosub, CaptureN
return

#If

;======== Main Script ========

_Start:

#NoEnv
#SingleInstance force
Critical
SetBatchLines, 10ms
;----------------------
ToolName:="AHK Screen Capture Tool"
Version:="2.0"
WindowColor:="0xDDEEFF"
;----------------------
CoordMode, Mouse
CoordMode, Pixel
CoordMode, ToolTip
CoordMode, Menu
Menu, Tray, Add
Menu, Tray, Add, %ToolName%, MainShow
Menu, Tray, Default, %ToolName%
Menu, Tray, Tip, %ToolName%
Menu, Tray, Click, 1
Loop, 10
  Menu, MyMenu, Add, % "Capture &" Mod(A_Index,10), RunMenu
SysGet, nX, 76
SysGet, nY, 77
SysGet, nW, 78
SysGet, nH, 79
VarSetCapacity(bits, nW*nH*4, 0xFF)
;-------------------------------------
Gui, Main: Default
Gui, +AlwaysOnTop +Hwndgui_id -DPIScale +LabelGui
Gui, Margin, 15, 15
Gui, Color, %WindowColor%, White
Gui, Add, Picture, w500 h500 HwndhPic +Border
Gui, Add, Slider, x+15 hp vMySlider2 gMovePic
  +Center Page10 Line10 +Vertical NoTicks AltSubmit
Gui, Add, Slider, xm w500 vMySlider1 gMovePic
  +Center Page10 Line10 NoTicks AltSubmit
;--------------------
LineNumber:=n:=11, w:=15, k:=n*(n//2)+(n//2)+1, C_:=[]
Loop, % n*n {
  i:=A_Index, j:=i=1 ? "ym Section" : Mod(i,n)=1 ? "xs y+0" : "x+0"
  j.=i=k-n ? " +Border cRed +BackgroundWhite Vertical"
    : i=k+n ? " +Border cWhite +BackgroundRed Vertical"
    : i=k-1 ? " +Border cWhite +BackgroundRed"
    : i=k+1 ? " +Border cRed +BackgroundWhite" : ""
  r:=i=k+n ? 70 : i=k-n ? 35 : i=k-1 ? 70 : i=k+1 ? 35 : 0
  Gui, Add, Progress, w%w% h%w% %j% Hwndid -E0x20000, %r%
  C_.Push(id)
}
;--------------------
Gui, Font, s12 cGreen bold
Gui, Add, Edit, ym w306 h125 ReadOnly
  , % "`nAHK Screen Capture Tool`n`n<FeiYue Share>"
  . "`n`n1.Press PrintScreen to screenshot first, then "
  . "use the right-click menu+[0-9] key to capture points."
  . "`n`n2.You can use ALT+[0-9] combination hotkeys to capture points."
  . "`n`n3.Directional keys can be used for fine-tuning when capturing.`n"
;-------------------------------------
Gui, Font, s12 cBlue norm
Gui, Add, Edit, w180 ReadOnly
Gui, Add, Button, x+10 yp-3 gRunButton, Clear Group
;-------------------------------------
Gui, Font, s14 cEE6600 bold
Gui, Add, Tab3, xs vMyTab gRunTab AltSubmit -Wrap Section
  , Group1|Group2|Group3|Group4|Group5
Gui, Font, s12 cBlue norm
C2_:=[]
Loop, 5 {
  Gui, Tab, %A_Index%
  Loop, 10 {
    i:=Mod(A_Index,10), j:=i=1 ? "xs+15 y+15":"xs+15 y+3"
    Gui, Add, Text, %j%, Capture %i%
    Gui, Add, Edit, x+10 w200 +Hwndid
    C2_.Push(id)
    Gui, Add, Progress, x+0 w25 hp +Border
      +Hwndid Background%WindowColor%
    C2_.Push(id)
    Gui, Add, Button, x+10 yp-3 gRunButton, Copy %i%
    Gui, Add, Button, x+0 gRunButton, Clear %i%
  }
}
Gui, Tab
MySlider1:=MySlider2:=0, MyTab:=1
;-------------------------------------
Gui, SubPic: Default
Gui, +Parent%hPic% -Caption -DPIScale +LabelGui
Gui, Margin, 0, 0
Gui, Color, White
Gui, Add, Picture, x0 y0 w%nW% h%nH% +HwndhPic2 +0xE
Gui, Show, NA x0 y0 w%nW% h%nH%, SubPic
;-------------------------------------
Gui, Main: Show,, %ToolName% v%Version% - By FeiYue
OnMessage(0x201, Func("LButton_Down"))
SetTimer, ReDraw, 200
return

ReDraw() {
  ListLines, Off
  global LineNumber, C_
  static C3_:=[]
  if !MouseIsOver()
    return
  MouseGetPos, px, py
  c:=GetPosAndColor(px, py, x, y)
  if (C3_[0]=x "," y)
    return
  C3_[0]:=x "," y, c:=Format("0x{:06X}", c)
  GuiControl, Main:, Edit2, %x%`, %y%`, %c%
  n:=LineNumber, k:=n*(n//2)+(n//2)+1, i:=0
  Loop, %n% {
    py:=y-(n//2)+A_Index-1
    Loop, %n% {
      px:=x-(n//2)+A_Index-1, i++
      if !(i=k-1||i=k+1||i=k-n||i=k+n)
        if (c:=GetColor(px,py))!=C3_[i]
          C3_[i]:=c, SetColor(c, C_[i])
    }
  }
  SetTimer, ReDraw
}

LButton_Down() {
  if (A_Gui="Main" && A_GuiControl="")
    SendMessage, 0xA1, 2
  else if (A_Gui="SubPic")
    Drag()
}

Drag() {
  global hPic, hPic2, nW, nH
  ListLines, Off
  VarSetCapacity(ret, 16, 0)
  DllCall("GetClientRect", "ptr",hPic, "ptr",&ret)
  DllCall("ClientToScreen", "ptr",hPic, "ptr",&ret)
  x:=NumGet(ret, 0, "int"), y:=NumGet(ret, 4, "int")
  w:=NumGet(ret, 8, "int"), h:=NumGet(ret, 12, "int")
  WinGetPos, winx, winy,,, ahk_id %hPic2%
  winx-=x, winy-=y
  MouseGetPos, x1, y1
  While GetKeyState("LButton", "P")
  {
    MouseGetPos, x2, y2
    x:=winx+x2-x1, y:=winy+y2-y1
    x:=x<-(nW-w) ? -(nW-w) : x>0 ? 0 : x
    y:=y<-(nH-h) ? -(nH-h) : y>0 ? 0 : y
    Gui, SubPic: Show, NA x%x% y%y%
    GuiControl, Main:, MySlider1, % Round(-x/(nW-w)*100)
    GuiControl, Main:, MySlider2, % Round(-y/(nH-h)*100)
    Sleep, 10
  }
}

GuiEscape:
Gui, Main: Hide
return

MainShow:
Gui, Main: Show
return

RunTab:
GuiControlGet, MyTab, Main:, MyTab
return

GuiContextMenu:
if (A_Gui="SubPic")
{
  MouseGetPos, px, py
  Menu, MyMenu, Show, %px%, %py%
}
return

RunMenu:
n:=A_ThisMenuItemPos
CaptureN:
Gosub, RunTab
c:=GetPosAndColor(px, py, x, y)
n:=(MyTab-1)*20+2*n-1+20*(!n)
c:=Format("0x{:06X}", c)
GuiControl, Main:, % C2_[n], %x%`, %y%`, %c%
SetColor(c, C2_[n+1])
return

MovePic:
ListLines, Off
VarSetCapacity(ret, 16, 0)
DllCall("GetClientRect", "ptr",hPic, "ptr",&ret)
w:=NumGet(ret, 8, "int"), h:=NumGet(ret, 12, "int")
x:=-(nW-w)*MySlider1//100
y:=-(nH-h)*MySlider2//100
Gui, SubPic: Show, NA x%x% y%y%
return

RunButton:
Gosub, RunTab
k:=A_GuiControl, n:=RegExReplace(k, "\D+")
n:=(MyTab-1)*20+2*n-1+20*(!n)
if InStr(k, "Group")
{
  Loop, 10 {
    n:=(MyTab-1)*20+2*A_Index-1
    GuiControl, Main:, % C2_[n]
    SetColor(WindowColor, C2_[n+1])
  }
}
else if InStr(k, "Copy")
{
  GuiControlGet, r, Main:, % C2_[n]
  Clipboard:=r
}
else
{
  GuiControl, Main:, % C2_[n]
  SetColor(WindowColor, C2_[n+1])
}
ToolTip, %k% OK !
SetTimer, Tip_Off, -500
return
Tip_Off:
ToolTip
return

SetColor(c, hwnd)
{
  c:=((c&0xFF)<<16)|(c&0xFF00)|((c&0xFF0000)>>16)
  SendMessage, 0x2001, 0, c,, ahk_id %hwnd%
}

GetPosAndColor(px, py, ByRef x="", ByRef y="")
{
  global
  VarSetCapacity(pt,8), NumPut(py,NumPut(px,pt,"int"),"int")
  DllCall("ScreenToClient", "ptr",hPic2, "ptr",&pt)
  x:=NumGet(pt,0,"int")+nX, y:=NumGet(pt,4,"int")+nY
  return, GetColor(x, y)
}

GetColor(x, y)
{
  global
  if (x<nX or y<nY or x>nX+nW-1 or y>nY+nH-1)
    return, 0xFFFFFF
  c:=NumGet(bits, (y-nY)*(nW*4)+(x-nX)*4, "uint")
  return, c&0xFFFFFF
}

PrintScreen(x, y, w, h, ByRef bits)
{
  static hBM, Ptr:=A_PtrSize ? "UPtr" : "UInt"
  DllCall("DeleteObject", Ptr,hBM)
  hBM:=CreateDIBSection(w, -h, 0, 32, ppvBits)
  win:=DllCall("GetDesktopWindow", Ptr)
  hDC:=DllCall("GetWindowDC", Ptr,win, Ptr)
  mDC:=DllCall("CreateCompatibleDC", Ptr,hDC, Ptr)
  oBM:=DllCall("SelectObject", Ptr,mDC, Ptr,hBM, Ptr)
  DllCall("BitBlt", Ptr,mDC, "int",0, "int",0, "int",w, "int",h
    , Ptr,hDC, "int",x, "int",y, "uint",0xCC0020|0x40000000)
  DllCall("RtlMoveMemory", Ptr,&bits, Ptr,ppvBits, Ptr,(w*4)*h)
  DllCall("ReleaseDC", Ptr,win, Ptr,hDC)
  hBrush:=DllCall("CreateSolidBrush", "uint",0xFFFFFF, Ptr)
  oBrush:=DllCall("SelectObject", Ptr,mDC, Ptr,hBrush, Ptr)
  DllCall("BitBlt", Ptr,mDC, "int",0, "int",0, "int",w, "int",h
    , Ptr,mDC, "int",0, "int",0, "uint",0xC000CA)
  DllCall("SelectObject", Ptr,mDC, Ptr,oBrush, Ptr)
  DllCall("DeleteObject", Ptr,hBrush)
  DllCall("SelectObject", Ptr,mDC, Ptr,oBM)
  DllCall("DeleteDC", Ptr,mDC)
  return, hBM
}

CreateDIBSection(w, h, hdc=0, bpp=32, ByRef ppvBits=0)
{
  Ptr:=A_PtrSize ? "UPtr" : "UInt", PtrP:=Ptr "*"
  VarSetCapacity(bi, 40, 0), NumPut(40, bi, 0, "int")
  NumPut(w, bi, 4, "int"), NumPut(h, bi, 8, "int")
  NumPut(1, bi, 12, "short"), NumPut(bpp, bi, 14, "short")
  hbm:=DllCall("CreateDIBSection", Ptr,hdc, Ptr,&bi
    , "int",0, PtrP,ppvBits, Ptr,0, "uint",0, Ptr)
  return, hbm
}

SetImage(hwnd, hBitmap)
{
  SendMessage, 0x172, 0x0, hBitmap,, ahk_id %hwnd%
  E:=ErrorLevel
  DllCall("DeleteObject", A_PtrSize ? "UPtr" : "UInt",E)
  return E
}

;======== Script End ========

;
Last edited by feiyue on 22 Apr 2019, 19:21, edited 6 times in total.
burque505
Posts: 971
Joined: 22 Jan 2017, 19:37

Re: AHK Screen Capture Tool

20 Apr 2019, 12:36

@feiyue, bravo! :bravo:
Regards,
burque505
User avatar
elModo7
Posts: 104
Joined: 01 Sep 2017, 02:38

Re: AHK Screen Capture Tool

02 May 2019, 11:12

Nice!
:beer:
Ridwan
Posts: 140
Joined: 17 Oct 2015, 21:06
Location: Indonesia

Re: AHK Screen Capture Tool

04 May 2019, 11:24

Can we save the captured image? Something like screenshot.
SOTE
Posts: 654
Joined: 15 Jun 2015, 06:21

Re: AHK Screen Capture Tool

04 May 2019, 12:18

Another nice one by Feiyue.

Return to “Scripts and Functions”

Who is online

Users browsing this forum: oldbrother and 29 guests