Jump to content

Drawing a rectangle to select an area

Recommended Posts

Hi all,

i'm developing a GIS (Geographical Information System) for my customers.

I need to let user select a square area on a map.

Right now I use a workaround that need user go to map and "ALT-1" to pick top-left and again to pick "bottom-right"

I used this GLOBAL

HotKeySet("!1!", "_Pickcoords") ; Alt-1

This GUI

$Label4 = GUICtrlCreateLabel("Top Left", 8, 130, 44, 17)
$topleft = GUICtrlCreateInput("", 80, 128, 121, 21, $ES_READONLY)
$Label5 = GUICtrlCreateLabel("Bottom Right", 8, 162, 65, 17)
$bottomright = GUICtrlCreateInput("", 80, 160, 121, 21, $ES_READONLY)
$settopleft = GUICtrlCreateButton("Set", 208, 126, 75, 25)
$setbottomright = GUICtrlCreateButton("Set", 208, 158, 75, 25)

This CASEs

Case $settopleft
        Case $setbottomright

and this functions

Func _SetCart($i)
    If $i = 1 Then
        MsgBox(0, "Info", "Move mouse to top left. Press ALT-1 when ready", 5)
    If $i = 2 Then
        MsgBox(0, "Info", "Move mouse to bottom right. Press ALT-1 when ready", 5)
    $coordkey = $i
EndFunc   ;==>_SetCart

Func _Pickcoords()
    Local $pos1
    If $coordkey = 1 Then
        $pos1 = MouseGetPos()
        GUICtrlSetData($topleft, $pos1[0] & "," & $pos1[1])
        _send("Top-Left position stored", $blucolor)
        $coordkey = 0
    ElseIf $coordkey = 2 Then
        $pos1 = MouseGetPos()
        GUICtrlSetData($bottomright, $pos1[0] & "," & $pos1[1])
        _send("Bottom-Right position stored", $blucolor)
        $coordkey = 0
EndFunc   ;==>_Pickcoords

It works without problems but my customers feels better (and easier) having a fixed square to move onto the map and just hitting a key (or a shortcut) to save coords than moving mouse top and bottom.

Something like the uploaded image.

So my question is: is it possible to have a fixed dimensions (let's say 300x200 but doesn't matter) rectangle to overlay it onto a map and, once correctly positioned, save topleft and bottomright coords?

Maybe @Melba23 or @Zelda could provide me some hints, obviously I'll be grateful to everyone for help.





Link to post
Share on other sites


here is a script on how to draw a square on desktop, about what you have asked for but it's ... well see yourself

#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <GDIPlus.au3>
#include <Misc.au3>


Local $hDLL = DllOpen("user32.dll")             ;Needed to catch the mouse key
local $hDC = _WinAPI_GetWindowDC(0)

Local $hGraphic = _GDIPlus_GraphicsCreateFromHDC($hDC)
Local $Color = 0xFF000000
local $hPen = _GDIPlus_PenCreate($Color, 2)
local $quit=0

While $quit = 0
_WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE + $RDW_ALLCHILDREN + $RDW_ERASE )
    $nX = MouseGetPos(0)
    $nY = MouseGetPos(1)
    _GDIPlus_GraphicsDrawRect($hGraphic, $nX-160, $nY-100, 320, 200, $hPen = 0)
    If _IsPressed("01", $hDLL) Then                 ;Mouse key 
        $quit = 1

sleep (60)

DllClose($hDLL)                                     ;Close the dll !
_WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE + $RDW_ALLCHILDREN)
_WinAPI_ReleaseDC(0, $hDC)

Local $Xtop=$nx-160
Local $yTop=$ny-100
Local $xbot=$xtop+320
Local $ybot=$ytop+200
MsgBox(0,"Click coordinate",$nx & " / " & $ny & @crlf & $Xtop & " / " & $yTop & " - " & $xbot & "/" & $ybot)

this is needed to catch a mouse press:

#include <Misc.au3>

Local $hDLL = DllOpen("user32.dll")
local $quit=0

While $quit = 0
    $nX = MouseGetPos(0)
    $nY = MouseGetPos(1)
    If _IsPressed("01", $hDLL) Then
        $quit = 1
sleep (60)


ConsoleWrite("Click coordinate " & $nx & " / " & $ny & @CRLF)


Edited by Dan_555
Link to post
Share on other sites

You could have a transparent GUI with a rectangle, and then uppon mouse click, delete the gui and replace it with the gdi functions, painting the rectangle. hope that made sense.


Renamer - Rename files and folders, remove portions of text from the filename etc.

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples


Link to post
Share on other sites
8 hours ago, marko001 said:

I see frames created by first code remains on screen creating a messy area (look attachment).

That's what the "..." in my post means. 



Does the browser (the map) need to be accessible while making selection? 

I mean, when the user makes the selection - the final click, the map is not moved/changed ?


#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
#include <Timers.au3>

Opt('MustDeclareVars', 1)
Global $hDLL = DllOpen("user32.dll")


Func _Main()
    Local $hGUI, $hBMP, $hBitmap, $hGraphic, $quit

    ; Capture upper left corner of screen
    $hBMP = _ScreenCapture_Capture("",0,0,-1,-1,False)
    ; Create GUI
    $hGUI = GUICreate("GDI+", @DesktopWidth, @DesktopHeight)

    ; Initialize GDI+ library

    ; Draw bitmap to GUI
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    ; Loop until user exits
        Local $nX = MouseGetPos(0)
        Local $nY = MouseGetPos(1)
        _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 0, 0)
        _GDIPlus_GraphicsDrawRect($hGraphic, $nX - 160, $nY - 100, 320, 200, 0)
        If Sleeper(80) Then
            $quit = True
    Until $quit = True

    ; Clean up resources

ConsoleWrite ($nx & " / " & $nY & @crlf)
EndFunc   ;==>_Main

Func Sleeper($nr)
    Local $exit = False
    Local $varTS = _Timer_Init()
    While _Timer_Diff($varTS) < $nr
        If _IsPressed("01", $hDLL) Then
            $exit = True
    Return $exit
EndFunc   ;==>Sleeper

This takes a Screenshot of the Desktop, opens a Gui, then draws the square. But interaction with the Browser is not possible. (and atm it works only on single monitor setup.)

Link to post
Share on other sites
  • Moderators


Here is my contribution - it uses a context menu to display and capture the coordinates once the rectangle is dragged to the correct place:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPISysWin.au3>

Global $hCapture_GUI


Func _Main()

    ; Create GUI
    Local $hMain_GUI = GUICreate("Select Rectangle", 240, 50)

    Local $hRect_Button = GUICtrlCreateButton("Mark Area", 10, 10, 80, 30)
    Local $hCancel_Button = GUICtrlCreateButton("Cancel", 150, 10, 80, 30)


    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE, $hCancel_Button
            Case $hRect_Button
                GUISetState(@SW_HIDE, $hMain_GUI)
                Local $aCoords = Mark_Rect()
                ; Show selected coords
                MsgBox($MB_SYSTEMMODAL, "Coords", $aCoords[0] & "x" &  $aCoords[1] & @CRLF & $aCoords[0] + $aCoords[2] & "x" & $aCoords[1] + $aCoords[3])
                GUISetState(@SW_SHOW, $hMain_GUI)

EndFunc   ;==>_Main

; -------------

Func Mark_Rect()

    ; Create capture GUI
    $hCapture_GUI = GUICreate("Y", 300, 200, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))

    ; Create label for dragging
    Local $cLabel = GUICtrlCreateLabel("", 0, 0, 300, 200, -1, $GUI_WS_EX_PARENTDRAG)
    GUICtrlSetBkColor(-1, 0xFF0000)

    ; Create context menu
    Local $cContextMenu = GUICtrlCreateContextMenu($cLabel)
    $cContext_Capture = GUICtrlCreateMenuItem("Capture", $cContextMenu)
    $cContext_Cancel = GUICtrlCreateMenuItem("Cancel", $cContextMenu)

    ; Hide GUI
    _WinAPI_SetLayeredWindowAttributes($hCapture_GUI, 0xABCDEF, 250)


    ; Set transparency level
    WinSetTrans($hCapture_GUI, "", 100)

    While 1

        Switch GUIGetMsg()
            Case $cContext_Capture
                ; Get GUI position and delete
                $aPos = WinGetPos($hCapture_GUI)
                ; Peturn position
                Return $aPos
            Case $cContext_Cancel

EndFunc   ;==>Mark_Rect


Edited by Melba23
Missing word

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:


ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...