Jump to content
marko001

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
            _SetCart(1)
        Case $setbottomright
            _SetCart(2)

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)
    EndIf
    $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
    EndIf
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.

Thanks,

Marco

 

SS_2058.jpg

Share this post


Link to post
Share on other sites
Posted (edited)

hi, 

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>

_GDIPlus_Startup()

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
    EndIf

sleep (60)
WEnd

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

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
    EndIf
sleep (60)
WEnd

DllClose($hDLL)

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

 

Edited by Dan_555

~Dan~ :Emu.Zone now with Desktop Pets / DeskMates - (Bugfixed UniScrMate 4.1)

Share this post


Link to post
Share on other sites

Thanks @Dan_555

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

Probably best would be "dragging" and self-creating the overlayered rectangle then acuiring positions

 

SS_2060.jpg

Share this post


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.


Spoiler

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

Au3Record.exe

Share this post


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. 

 

Question:

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")

_Main()

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)
    GUISetState()

    ; Initialize GDI+ library
    _GDIPlus_Startup()

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

    ; Loop until user exits
    Do
        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
        EndIf
        
    Until $quit = True

    _GDIPlus_Shutdown()
    ; Clean up resources
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_BitmapDispose($hBitmap)
    _WinAPI_DeleteObject($hBMP)

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
        EndIf
    WEnd
    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.)


~Dan~ :Emu.Zone now with Desktop Pets / DeskMates - (Bugfixed UniScrMate 4.1)

Share this post


Link to post
Share on other sites
Posted (edited)

marko001,

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

_Main()

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)

    GUISetState()

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE, $hCancel_Button
                Exit
            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)
        EndSwitch
    WEnd

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))
    GUISetBkColor(0xABCDEF)

    ; 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)

    GUISetState()

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

    While 1

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

EndFunc   ;==>Mark_Rect

M23

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:

Spoiler

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

 

Share this post


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...