selection rectangle: use mouse to select screen region

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

selection rectangle: use mouse to select screen region

15 Jan 2018, 01:26

- I wrote a script based on LetUserSelectRect by Lexikos:
LetUserSelectRect - select a portion of the screen - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/4592 ... he-screen/
- I've changed it to use a transparent filled-in rectangle, instead of opaque borders, and it now supports right-click/Esc to cancel, plus it's generally been rewritten.
- You press q, and then when you hold down the left mouse button, a red selection rectangle appears, and when you release the button, the rectangle disappears, and a printscreen is taken of that region and displayed using SplashImage.
- Pressing the right mouse button or Esc cancels the selection.
- Note: the script requires the Gdip/Gdip_All library.

- Problems are that: at the moment it requires CoordMode be set in the auto-execute section, it uses a global variable, and it uses labels within a function.
- I'm posting in case anyone has any suggestions on how to improve it.

Code: Select all

;[Gdip functions]
;GDI+ standard library 1.45 by tic - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=6517

CoordMode, Mouse, Screen

q:: ;take printscreen based on selection rectangle
DetectHiddenWindows, On
InputRect(vWinX, vWinY, vWinR, vWinB)
vWinW := vWinR-vWinX, vWinH := vWinB-vWinY
if (vInputRectState = -1)
	return

vScreen := vWinX "|" vWinY "|" vWinW "|" vWinH
pToken := Gdip_Startup()
pBitmap := Gdip_BitmapFromScreen(vScreen, 0x40CC0020)
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", Ptr,pBitmap, PtrP,hBitmap, Int,0xffffffff)

;SplashImage, % "HBITMAP:" hBitmap, B
SplashImage, % "HBITMAP:" hBitmap
Sleep, 2000
SplashImage, Off

DeleteObject(hBitmap)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return

;==================================================

;based on LetUserSelectRect by Lexikos:
;LetUserSelectRect - select a portion of the screen - Scripts and Functions - AutoHotkey Community
;https://autohotkey.com/board/topic/45921-letuserselectrect-select-a-portion-of-the-screen/

;note: 'CoordMode, Mouse, Screen' must be used in the auto-execute section

;e.g.
;InputRect(vWinX, vWinY, vWinR, vWinB)
;vWinW := vWinR-vWinX, vWinH := vWinB-vWinY
;if (vInputRectState = -1)
;	return

InputRect(ByRef vX1, ByRef vY1, ByRef vX2, ByRef vY2)
{
	global vInputRectState := 0
	DetectHiddenWindows, On
	Gui, 1: -Caption +ToolWindow +AlwaysOnTop +hWndhGuiSel
	Gui, 1: Color, Red
	WinSet, Transparent, 128, % "ahk_id " hGuiSel
	Hotkey, *LButton, InputRect_Return, On
	Hotkey, *RButton, InputRect_End, On
	Hotkey, Esc, InputRect_End, On
	KeyWait, LButton, D
	MouseGetPos, vX0, vY0
	SetTimer, InputRect_Update, 10
	KeyWait, LButton
	Hotkey, *LButton, Off
	Hotkey, Esc, InputRect_End, Off
	SetTimer, InputRect_Update, Off
	Gui, 1: Destroy
	return

	InputRect_Update:
	if !vInputRectState
	{
		MouseGetPos, vX, vY
		(vX < vX0) ? (vX1 := vX, vX2 := vX0) : (vX1 := vX0, vX2 := vX)
		(vY < vY0) ? (vY1 := vY, vY2 := vY0) : (vY1 := vY0, vY2 := vY)
		Gui, 1:Show, % "NA x" vX1 " y" vY1 " w" (vX2-vX1) " h" (vY2-vY1)
		return
	}
	vInputRectState := 1

	InputRect_End:
	if !vInputRectState
		vInputRectState := -1
	Hotkey, *LButton, Off
	Hotkey, *RButton, Off
	Hotkey, Esc, Off
	SetTimer, InputRect_Update, Off
	Gui, 1: Destroy

	InputRect_Return:
	return
}

;==================================================
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Flipeador
Posts: 1204
Joined: 15 Nov 2014, 21:31
Location: Argentina
Contact:

Re: selection rectangle: use mouse to select screen region

10 May 2018, 20:47

:)

Code: Select all

BW := 1

; ESC = EXIT
~Esc:: ExitApp

; LBUTTON = SHOW
LButton::
POINT := 0
DllCall("User32.dll\GetCursorPos", "Int64P", POINT)
SelRect(NumGet(&POINT, "Int"), NumGet(&POINT+4, "Int"),,, BW)
Return

; F1 = ++BORDER_WIDTH
F1:: ToolTip(++BW)
; F2 = --BORDER_WIDTH
F2:: ToolTip(--BW)


SelRect(X, Y, BackColor := "82C0FF", BorderColor := "0078D7", BW := 1, Transparent := 128, Delay := 50)
{
    Local Gui := GuiCreate("-Caption +ToolWindow +AlwaysOnTop +E0x8000000")
    Local Txt := [ BW, Gui.AddText("+E0x8000000 Background" . BackColor) ]
    Loop 4
        Txt[A_Index+2] := Gui.AddText("+E0x8000000 Background" . BorderColor)

    SetTimer("Update", -Delay)

    Update()
    {
        Local POINT := 0, CY := DllCall("User32.dll\GetCursorPos", "Int64P", POINT)
            ,    CX := NumGet(&POINT, "Int"), CY := NumGet(&POINT+4, "Int")
            ,    NW := CX - X, NH := CY - Y, Pos := Gui.Pos
            ,    NX := NW < 0 ? X + NW : X, NW := Abs(NW)
            ,    NY := NH < 0 ? Y + NH : Y, NH := Abs(NH)
        
        If (Pos.X != NX || Pos.Y != NY || Pos.W != NW || Pos.H != NH)
            Gui.Show("x" . NX . " y" . NY . " w" . NW . " h" . NH . " NA")
          , Txt[2].Move("x" . Txt[1] . " y" . Txt[1] . " w" . (NW-Txt[1]*2) . " h" . (NH-Txt[1]*2))
          , Txt[3].Move("x0 y0 w" . NW . " h" . Txt[1])
          , Txt[4].Move("x0 y0 w" . Txt[1] . " h" . NH)
          , Txt[5].Move("x" . (NW-Txt[1]) . " y0 w" . Txt[1] . " h" . NH)
          , Txt[6].Move("x0" . " y" . (NH-Txt[1]) . " w" . NW . " h" . Txt[1])
          , WinSetTransparent(Transparent, "ahk_id" . Gui.Hwnd)

        If (GetKeyState("LButton", "P"))
            SetTimer("Update", -Delay)
        Else
            Gui.Destroy()
    }
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 224 guests