Simple script for selecting screen area

Post your working scripts, libraries and tools for AHK v1.1 and older
feiyue
Posts: 349
Joined: 08 Aug 2014, 04:08

Simple script for selecting screen area

07 Jun 2018, 01:02

This is a simple script for selecting screen area. You can try it. :dance: :beer:

Code: Select all

/*
------------------------------------------
  Simple script for selecting screen area v1.8  By FeiYue

  Instructions:

  1.Press the hotkey "F1" to start the LButton key to drag the selection range.

    Then you can use the LButton key to adjust and RButton to determine the scope.

  2.Return the scope through 4 parameters.

------------------------------------------
*/

F1:: MsgBox, 4096, Tip, % GetRange(x,y,w,h)
  . "The selection range is : " x "," y "," w "," h

GetRange(ByRef x="",ByRef y="",ByRef w="",ByRef h="")
{
  ; Save the initial state and set the current state
  cmm:=A_CoordModeMouse
  CoordMode, Mouse, Screen

  ; Create canvas GUI
  nW:=A_ScreenWidth, nH:=A_ScreenHeight
  Gui, Canvas:New, +AlWaysOnTop +ToolWindow -Caption
  Gui, Canvas:Add, Picture, x0 y0 w%nW% h%nH% +0xE HwndPicID

  ; Create selection range GUI
  Gui, Range:New, +LastFound +AlWaysOnTop -Caption +Border
    +OwnerCanvas +HwndRangeID
  WinSet, Transparent, 100
  Gui, Range:Color, Yellow

  ; Screenshots to the memory image and sent to
  ; the picture control of the canvas window.
  Ptr:=A_PtrSize ? "UPtr":"UInt", int:="int"
  hDC:=DllCall("GetDC", Ptr,0, Ptr)
  mDC:=DllCall("CreateCompatibleDC", Ptr,hDC, Ptr)
  hBM:=DllCall("CreateCompatibleBitmap", Ptr,hDC, int,nW, int,nH, Ptr)
  oBM:=DllCall("SelectObject", Ptr,mDC, Ptr,hBM, Ptr)
  DllCall("BitBlt", Ptr,mDC, int,0, int,0, int,nW, int,nH
    , Ptr,hDC, int,0, int,0, int,0x00CC0020|0x40000000)
  DllCall("ReleaseDC", Ptr,0, Ptr,hDC)
  ;---------------------
  SendMessage, 0x172, 0, hBM,, ahk_id %PicID%
  if ( E:=ErrorLevel )
    DllCall("DeleteObject", Ptr,E)
  ;---------------------
  DllCall("SelectObject", Ptr,mDC, Ptr,oBM)
  DllCall("DeleteDC", Ptr,mDC)

  ; Display the canvas window and start to wait for the selection range
  Gui, Canvas:Show, NA x0 y0 w%nW% h%nH%

  ; Prompt to hold down the LButton key
  ListLines, Off
  oldx:=oldy:=""
  Loop {
    Sleep, 100
    MouseGetPos, x, y
    if (oldx=x and oldy=y)
      Continue
    oldx:=x, oldy:=y
    ;--------------------
    ToolTip, Please hold down LButton key to select a range
  }
  Until GetkeyState("LButton","P")

  ; Prompt to release the LButton key
  x1:=x, y1:=y, oldx:=oldy:=""
  Loop {
    Sleep, 100
    MouseGetPos, x, y
    if (oldx=x and oldy=y)
      Continue
    oldx:=x, oldy:=y
    ;--------------------
    w:=Abs(x1-x), h:=Abs(y1-y)
    x:=(x1+x-w)//2, y:=(y1+y-h)//2
    Gui, Range:Show, NA x%x% y%y% w%w% h%h%
    ToolTip, Please drag the mouse and release the LButton key
  }
  Until !GetkeyState("LButton","P")

  ; Prompt to click the RButton key to determine the range
  oldx:=oldy:=""
  Loop {
    Sleep, 100
    MouseGetPos, x, y, id
    if (id=RangeID) and GetkeyState("LButton","P")
    {
      WinGetPos, x1, y1,,, ahk_id %RangeID%
      Loop {
        Sleep, 100
        MouseGetPos, x2, y2
        Gui, Range:Show, % "NA x" x1+x2-x " y" y1+y2-y
      }
      Until !GetkeyState("LButton","P")
    }
    if (oldx=x and oldy=y)
      Continue
    oldx:=x, oldy:=y
    ;--------------------
    ToolTip, Please click the RButton key to determine the scope`,`n
    and use the LButton key can adjust the scope
  }
  Until GetkeyState("RButton","P")
  KeyWait, RButton
  ToolTip
  ListLines, On

  ; Clean the canvas and selection range GUI
  WinGetPos, x, y, w, h, ahk_id %RangeID%
  Gui, Range:Destroy
  Gui, Canvas:Destroy

  ; Clean the memory image and restore the initial state
  DllCall("DeleteObject", Ptr,hBM)
  CoordMode, Mouse, %cmm%
}


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

;
Last edited by feiyue on 07 Jun 2018, 16:51, edited 2 times in total.
burque505
Posts: 1734
Joined: 22 Jan 2017, 19:37

Re: Simple script for selecting screen area

07 Jun 2018, 07:19

Thank you, feiyue, that's a very nice script.
Regards,
burque505
toralf
Posts: 868
Joined: 27 Apr 2014, 21:08
Location: Germany

Re: Simple script for selecting screen area

07 Jun 2018, 10:20

Thanks feiyue for sharing,
Could you please explain why you use a canvas GUI? It seems a lot of overhead. What is the benefit?
ciao
toralf
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: Simple script for selecting screen area

07 Jun 2018, 12:44

nice.

i always used this old alternative function:

Code: Select all

;// http://www.autohotkey.com/forum/topic62195.html
;//
;// Rbutton::MsgBox,,, % SelectArea(), 1.5
;// Rbutton::MsgBox,,, % SelectArea("cLime t100 g55 mr"), 1.5

SelectArea(Options="") {   ; by Learning one
   /*
   Returns selected area. Return example: 22|13|243|543
   Options: (White space separated)
   - c color. Default: Blue.
   - t transparency. Default: 50.
   - g GUI number. Default: 99.
   - m CoordMode. Default: s. s = Screen, r = Relative
   */
   CoordMode, Mouse, Screen
   MouseGetPos, MX, MY
   CoordMode, Mouse, Relative
   MouseGetPos, rMX, rMY
   CoordMode, Mouse, Screen
   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 , m := (m = "") ? "s" : m
   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
   if m = s   ; Screen
   {
      MouseGetPos, MXend, MYend
      If ( MX > MXend )
      temp := MX, MX := MXend, MXend := temp
      If ( MY > MYend )
      temp := MY, MY := MYend, MYend := temp
      Return MX "|" MY "|" MXend "|" MYend
   }
   else   ; Relative
   {
      CoordMode, Mouse, Relative
      MouseGetPos, rMXend, rMYend
      If ( rMX > rMXend )
      temp := rMX, rMX := rMXend, rMXend := temp
      If ( rMY > rMYend )
      temp := rMY, rMY := rMYend, rMYend := temp
      Return rMX "|" rMY "|" rMXend "|" rMYend
   }
}

feiyue
Posts: 349
Joined: 08 Aug 2014, 04:08

Re: Simple script for selecting screen area

07 Jun 2018, 17:14

@guest3456, You're using another good script. :thumbup:

@toralf, I add a background canvas that seems unnecessary, It's just for fun. :D

The advantage of using background canvas is that it is easy to select the scope and then screenshots,
so that the current static picture can be retained.

The feature of this script is that after selecting the scope, you can drag the GUI window for fine tuning..
rickyc
Posts: 5
Joined: 04 Jun 2018, 01:41

Re: Simple script for selecting screen area

22 Jun 2018, 02:20

Thanks for sharing this wonderful idea as I was searching for an easy method. This gave me an idea on how to select an screen area. :salute: Perfectly.

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 144 guests