Jump to content

_GUIBox - Rubberband selection boxes using GUIs


Recommended Posts

_GUIBox

Rubberband selection boxes using GUIs

Posted Image

Create Rectangles using GUI boxes. Great for Rubber-band selection (as an alternative to DrawFocusRect), or just putting box outlines on the screen period!

Example code included (including rubber-band style box-selection simulation).

#include <_GUIBox.au3>
; ===============================================================================================================================
; <TestGUIBox.au3>
;
;   Tests for _GUIBox UDF.
;
; Author: Ascend4nt
; ===============================================================================================================================

; ===================================================================================================================
; GLOBAL VARIABLES
; ===================================================================================================================

Global $bEscPressed=False,$bHomeKeyPressed=False,$bEndKeyPressed=False,$aHomeLoc[2]=[-1,-1]

; ===================================================================================================================
; HOTKEY FUNCTIONS
; ===================================================================================================================

Func _EscHotKeyPressed()
    $bEscPressed=True
EndFunc

Func _HomeKeyPressed()
    If Not $bHomeKeyPressed Then
        $bHomeKeyPressed=True
        $aHomeLoc=MouseGetPos()
    EndIf
EndFunc

Func _EndKeyPressed()
    If $bHomeKeyPressed Then $bEndKeyPressed=True
EndFunc

; ===================================================================================================================
; MAIN START
; ===================================================================================================================

Test1()
Test2()

; Test 1
Func Test1()
    MsgBox(0,"Rubber-Band Box Example","After Clicking OK, the Rubber-Band GUI-Box Example will start."&@CRLF& _
        "Press [Home] to set the initial Box start, and then [End] to set the end location of the box."&@CRLF& _
        "You may stop the routine at any time by pressing [Escape].")

    HotKeySet("{ESC}","_EscHotKeyPressed")

    Dim $aCurMousePos,$aRubberBandGBox

    $aRubberBandGBox=_GBoxCreate("",3,0xFF0000)
    HotKeySet("{HOME}","_HomeKeyPressed")
    HotKeySet("{END}","_EndKeyPressed")

    While Not $bEscPressed And Not $bEndKeyPressed
        If $bHomeKeyPressed Then
            $aCurMousePos=MouseGetPos()
            _GBoxShowAt($aRubberBandGBox,$aHomeLoc[0],$aHomeLoc[1],$aCurMousePos[0],$aCurMousePos[1])
        EndIf
        Sleep(5)
    WEnd
    If $bHomeKeyPressed And IsArray($aCurMousePos) Then
        MsgBox(0,"Rubber-band box example complete","Last coordinates of the Rubber-band box: "& _
            "X1:"&$aHomeLoc[0]&" Y1:"&$aHomeLoc[1]&" X2:"&$aCurMousePos[0]&" Y2:"&$aCurMousePos[1])
    EndIf
    _GBoxDestroy($aRubberBandGBox)
EndFunc

; Test 2
Func Test2()
    Local $aBugaBox,$aBoxRed,$aBoxGreen,$aBoxBlue,$aBoxFADED

    $aBugaBox=_GBoxCreate()
    $aBoxRed=_GBoxCreate("",5,0XFF0000)
    $aBoxGreen=_GBoxCreate("",1,0xFF00)
    $aBoxBlue=_GBoxCreate("",1,0xFF)
    $aBoxFADED=_GBoxCreate("",1,0x0FADED)

    MsgBox(0,"Test 2 - Multiple GUI Boxes","Ready to show boxes - Click OK")

    _GBoxShowAt($aBugaBox,100,100,800,800)
    _GBoxShowAt($aBoxRed,300,400,700,700)
    _GBoxShowAt($aBoxGreen,400,800,402,802)
    _GBoxShowAt($aBoxBlue,801,200,900,900)
    _GBoxShowAt($aBoxFADED,410,410,790,790)

    MsgBox(0,"Now to Hide them","Click OK to Hide the boxes now")

    _GBoxHide($aBugaBox)
    _GBoxHide($aBoxRed)
    _GBoxHide($aBoxGreen)
    _GBoxHide($aBoxBlue)
    _GBoxHide($aBoxFADED)

    MsgBox(0,"Now to Redisplay Them","Click OK to Re-display the boxes, though one will have a new color, transparency, and thickness")

    _GBoxSetDisplayProps($aBugaBox,3,0x0899CC,255)  ; Changing the thickness, color, and transparency (to non-transparent)
    ; Since the box was invisible, we need to force it to recognize a resize (last parameter=True) as we altered the thickness
    ;   If we had instead put _GboxShow($aBugaBox) prior to _GBoxSetDisplayProps(), we would not need to force a resize
    _GBoxShow($aBugaBox,False,True)
    _GBoxShow($aBoxRed)
    _GBoxShow($aBoxGreen)
    _GBoxShow($aBoxBlue)
    _GBoxShow($aBoxFADED)

    MsgBox(0,"That's all folks!","Now click OK to delete")

    _GBoxDestroy($aBugaBox)
    _GBoxDestroy($aBoxRed)
    _GBoxDestroy($aBoxGreen)
    _GBoxDestroy($aBoxBlue)
    _GBoxDestroy($aBoxFADED)
EndFunc

Download the ZIP from my site

Ascend4nt's AutoIT Code License agreement:

While I provide this source code freely, if you do use the code in your projects, all I ask is that:

  • If you provide source, keep the header as I have put it, OR, if you expand it, then at least acknowledge me as the original author, and any other authors I credit
  • If the program is released, acknowledge me in your credits (it doesn't have to state which functions came from me, though again if the source is provided - see #1)
  • The source on it's own (as opposed to part of a project) can not be posted unless a link to the page(s) where the code were retrieved from is provided and a message stating that the latest updates will be available on the page(s) linked to.
  • Pieces of the code can however be discussed on the threads where Ascend4nt has posted the code without worrying about further linking.
*edit: clarified with the word 'outlines' so as not to confuse people. (creating resizable solid boxes is a much simpler task not even needing a UDF - I just posted code to do exactly this -> ) Edited by Ascend4nt
Link to post
Share on other sites
  • 2 months later...
Such a great script. However, I see in the source file that $iGBoxColor = background color but in fact, it's the border color of the box not the background one. So can you add an option to set the background color of the box and its transparency as well? Thanks Edited by Bot
Link to post
Share on other sites

Such a great script. However, I see in the source file that $iGBoxColor = background color but in fact, it's the border color of the box not the background one. So can you add an option to set the background color of the box and its transparency as well? Thanks

Are you kidding? What do you suppose this line does?:

GUISetBkColor($iGBoxColor,$aBoxRet[$i])

The GUI's are created *without* borders, so I don't know where you get the idea that there even is one.

*edit: Bot, I think you misunderstood - if you are looking to create full boxes (not outlines like my code creates), then you've got a much simpler task. I clarified the wording in my first post, hopefully that should make it more clear. The 'outline' created by my code is actually 4 separate GUI's.

Edited by Ascend4nt
Link to post
Share on other sites

Are you kidding? What do you suppose this line does?:

GUISetBkColor($iGBoxColor,$aBoxRet[$i])

The GUI's are created *without* borders, so I don't know where you get the idea that there even is one.

*edit: Bot, I think you misunderstood - if you are looking to create full boxes (not outlines like my code creates), then you've got a much simpler task. I clarified the wording in my first post, hopefully that should make it more clear. The 'outline' created by my code is actually 4 separate GUI's.

OK I see. Then I will create a full box. Thanks for your answer :mellow:
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.

  • Similar Content

    • By Dan_555
      Hi, here are few functions for the ListBox.
      I have searched the forum, but most of the functions are for listview, so i took one example code from melba23 (clear selection) and
      wrote few more functions. (Because my current project needs them).
       
      These functions work only on a Multi-selection ListBox . 
      Edit: Only 1 function does not work with single selection box.
      The functions do: Clear Selection, Delete Selected items, Invert Selection, Move selected items up and down.
       The example code has 2 Listboxes. The selected items on the left ListBox can be moved up and down. The right Listbox has buttons for the other functions.
      #include <GUIConstantsEx.au3> #include <GuiListBox.au3> #include <WindowsConstants.au3> #include <Array.au3> Local $singlesel = 0, $iMsgBoxAnswer = 0 ;MsgBox features: Title=Yes, Text=Yes, Buttons=Yes and No, Icon=Question, Modality=Task Modal $iMsgBoxAnswer = MsgBox(8228, "Choose Listbox selecton type", "Yes for single, No for multi selection box") If $iMsgBoxAnswer = 6 Then $singlesel = 1 ;Yes Local $BL_1,$BL_2,$BR_1,$BR_2,$BR_3,$BR_4,$BR_5,$BR_6 Global $hForm1 = GUICreate("Listbox test", 349, 287) $LB_1 = GUICtrlCreateList("", 6, 40, 157, 244, BitOR($LBS_NOTIFY, $LBS_MULTIPLESEL, $WS_HSCROLL, $WS_VSCROLL, $LBS_DISABLENOSCROLL)) If $singlesel = 1 Then $LB_2 = GUICtrlCreateList("", 179, 40, 157, 244, BitOR($LBS_NOTIFY, $WS_HSCROLL, $WS_VSCROLL, $LBS_DISABLENOSCROLL)) Else $LB_2 = GUICtrlCreateList("", 179, 40, 157, 244, BitOR($LBS_NOTIFY, $LBS_MULTIPLESEL, $WS_HSCROLL, $WS_VSCROLL, $LBS_DISABLENOSCROLL)) $BR_3 = GUICtrlCreateButton("Reverse Sel", 272, 22, 68, 17) EndIf $BL_1 = GUICtrlCreateButton("Up", 20, 3, 35, 18) $BL_2 = GUICtrlCreateButton("Down", 60, 3, 35, 18) $BR_1 = GUICtrlCreateButton("Up", 200, 3, 35, 18) $BR_2 = GUICtrlCreateButton("Down", 240, 3, 35, 18) $BR_4 = GUICtrlCreateButton("Clear Sel", 217, 22, 52, 17) $BR_5 = GUICtrlCreateButton("Delete", 175, 22, 40, 17) $BR_6 = GUICtrlCreateButton("Populate", 290, 3, 50, 18) GUISetState(@SW_SHOW) For $x = 0 To 50 If $x <= 10 Then GUICtrlSetData($LB_1, $x & " test", 0) GUICtrlSetData($LB_2, $x & " Test", 0) Next While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $BL_1 $a = Listbox_ItemMoveUD($LB_1, -1) If $a > -1 Then WinSetTitle($hForm1, "", "Moved items: " & $a) Case $BL_2 $a = Listbox_ItemMoveUD($LB_1, 1) If $a > -1 Then WinSetTitle($hForm1, "", "Moved items: " & $a) Case $BR_1 Listbox_ItemMoveUD($LB_2, -1) Case $BR_2 Listbox_ItemMoveUD($LB_2, 1) Case $BR_3 Listbox_ReverseSelection($LB_2) Case $BR_4 Listbox_ClearSelection($LB_2) Case $BR_5 Listbox_DeleteSelectedItems($LB_2) Case $BR_6 ;Populate GUICtrlSetData($LB_2, "") ; Clears the listbox For $x = 0 To 50 GUICtrlSetData($LB_2, $x & " Test", 0) Next EndSwitch WEnd ;note $hLB_ID - is the Listbox id Func Listbox_DeleteSelectedItems($hLB_ID) Local $aSel = _GUICtrlListBox_GetSelItems($hLB_ID) ;Get selected items Local $i, $slb = 0, $y, $x If $aSel[0] = 0 Then ;If the array is empty, there is no selection, or it is a single selection listbox For $x = 0 To _GUICtrlListBox_GetCount($hLB_ID) - 1 $y = _GUICtrlListBox_GetSel($hLB_ID, $x) If $y = True Then $slb = 1 _GUICtrlListBox_DeleteString($hLB_ID, $x) ;Perform a delete on single sel. LB ExitLoop EndIf Next EndIf If $slb = 0 Then _GUICtrlListBox_BeginUpdate($hLB_ID) For $i = $aSel[0] To 1 Step -1 ;Loop backwards and delete the selected items _GUICtrlListBox_DeleteString($hLB_ID, $aSel[$i]) Next _GUICtrlListBox_EndUpdate($hLB_ID) EndIf EndFunc ;==>Listbox_DeleteSelectedItems Func Listbox_ClearSelection($hLB_ID) ;Removes the selection from multi and single selection ListBox Local $aSel = _GUICtrlListBox_GetSelItems($hLB_ID) ;Code from Melba23 - Autoit Forum Local $slb, $x, $y If $aSel[0] = 0 Then _GUICtrlListBox_SetCurSel($hLB_ID, -1) $slb = 1 EndIf If $slb = 0 Then _GUICtrlListBox_BeginUpdate($hLB_ID) For $i = 1 To $aSel[0] _GUICtrlListBox_SetSel($hLB_ID, $aSel[$i], False) Next _GUICtrlListBox_EndUpdate($hLB_ID) EndIf EndFunc ;==>Listbox_ClearSelection Func Listbox_ReverseSelection($hLB_ID) ;Logically, this function works only on multi-selection listboxes Local $i Local $aCou = _GUICtrlListBox_GetCount($hLB_ID) Local $cSel = _GUICtrlListBox_GetCaretIndex($hLB_ID) ;Save the caret _GUICtrlListBox_BeginUpdate($hLB_ID) For $i = 0 To $aCou _GUICtrlListBox_SetSel($hLB_ID, $i, Not (_GUICtrlListBox_GetSel($hLB_ID, $i))) Next _GUICtrlListBox_SetCaretIndex($hLB_ID, $cSel) ;Restore the caret _GUICtrlListBox_EndUpdate($hLB_ID) EndFunc ;==>Listbox_ReverseSelection Func Listbox_ItemMoveUD($hLB_ID, $iDir = -1) ;Listbox_ItemMoveUD - Up/Down Move Multi/Single item in a ListBox ;$iDir: -1 up, 1 down ;Return values -1 nothing to do, 0 nothing moved, >0 performed moves Local $iCur, $iNxt, $aCou, $aSel, $i, $m = 0, $y, $slb = 0 ;Current, next, Count, Selection, loop , movecount $aSel = _GUICtrlListBox_GetSelItems($hLB_ID) ;Put selected items in an array $aCou = _GUICtrlListBox_GetCount($hLB_ID) ;Get total item count of the listbox If $aSel[0] = 0 Then $y = _GUICtrlListBox_GetCurSel($hLB_ID) If $y > -1 Then _ArrayAdd($aSel, $y) $aSel[0] = 1 $slb = 1 EndIf EndIf ;WinSetTitle($hGUI, "", $aSel[0]) ;Debugging info Select Case $iDir = -1 ;Move Up For $i = 1 To $aSel[0] If $aSel[$i] > 0 Then $iNxt = _GUICtrlListBox_GetText($hLB_ID, $aSel[$i] - 1) ;Save the selection index - 1 text _GUICtrlListBox_ReplaceString($hLB_ID, $aSel[$i] - 1, _GUICtrlListBox_GetText($hLB_ID, $aSel[$i])) ;Replace the index-1 text with the index text _GUICtrlListBox_ReplaceString($hLB_ID, $aSel[$i], $iNxt) ;Replace the selection with the saved var $m = $m + 1 EndIf Next For $i = 1 To $aSel[0] ;Restore the selections after moving If $aSel[$i] > 0 Then If $slb = 0 Then _GUICtrlListBox_SetSel($hLB_ID, $aSel[$i] - 1, 1) Else _GUICtrlListBox_SetCurSel($hLB_ID, $aSel[$i] - 1) EndIf EndIf Next Return $m Case $iDir = 1 ;Move Down If $aSel[0] > 0 Then For $i = $aSel[0] To 1 Step -1 If $aSel[$i] < $aCou - 1 Then $iNxt = _GUICtrlListBox_GetText($hLB_ID, $aSel[$i] + 1) _GUICtrlListBox_ReplaceString($hLB_ID, $aSel[$i] + 1, _GUICtrlListBox_GetText($hLB_ID, $aSel[$i])) _GUICtrlListBox_ReplaceString($hLB_ID, $aSel[$i], $iNxt) $m = $m + 1 EndIf Next EndIf For $i = $aSel[0] To 1 Step -1 ;Restore the selections after moving If $aSel[$i] < $aCou - 1 Then If $slb = 0 Then _GUICtrlListBox_SetSel($hLB_ID, $aSel[$i] + 1, 1) Else _GUICtrlListBox_SetCurSel($hLB_ID, $aSel[$i] + 1) EndIf EndIf Next Return $m EndSelect Return -1 EndFunc ;==>Listbox_ItemMoveUD  
    • By nacerbaaziz
      hi dears, i have a question please
      am now working for an audio player for the blind users
      and i added an option to open a file from the right click context menu.
      but here there is a small problem, i hope that you can help me to find a solution for it.
      the problem is as follow :
      when i added the problem into the context menu it work with successfuly if the user select just one file.
      but if the user selected more then one file, here the problem
      a multiple sections of the program will open.
      my question is :
      how i can detect the multiple selection from the context menu?
      i know that it so  hard, but i know also that you are harder than it
      for that dears please try to give me an solution for that problem.
      thanks in advance
    • By TheDcoder
      Hello, it has been a long time since I have posted here
      I am working on an AutoIt project where I need to enable to user to interactively choose any point or coordinate on the screen... something like a big overlay where the user can click anywhere on the screen to select that point. @UEZ's screenshot tool may have something similar to what I need:
      I just checked the source code for the tool and I see that the Mark_Area function has a part in selecting the area to screenshot, I tried to figure out how it works but it is simply too complex and long...
      So I was wondering if there were any examples of interactively selecting points on a screen? Maybe an UDF that I can just use in my script to make the whole thing a matter of adding few lines
      Thank you for the replies in advance!
    • By ahha
      I'm using the excellent _Excel UDF to read a whole spreadsheet into an array I want to operate on.  I can read a specified range without a problem.  What I'd like to do is allow the user in Excel to select a range (contiguous is fine) and be able to read that range so that I know what range to operate on without having the user input the range via a keyboard.  I'm stuck and any hints greatly appreciated.  The code below uses the Helpfile .xls to illustrate where I crash.
      ; #AutoIt3Wrapper_run_debug_mode=Y ; use this to debug in console window <--- LOOK #include <Excel.au3> #include <MsgBoxConstants.au3> #include <Debug.au3> ;for _DebugArrayDisplay $sExcelFullFileName = "C:\Program Files (x86)\AutoIt3\Examples\Helpfile\Extras\_Excel1.xls" ;use Autoit test for example $oExcel = _Excel_Open() ;Create application object and open an Excel workbook $oWorkbook = _Excel_BookOpen($oExcel, $sExcelFullFileName) $aExcelArray = _Excel_RangeRead($oWorkbook, Default) _DebugArrayDisplay($aExcelArray, $aExcelArray) ;let's look at it $aI5K6 = _Excel_RangeRead($oWorkbook, Default,"I5:K6") ;read a rangeI5:K6 and return value _DebugArrayDisplay($aI5K6, $aI5K6) ;let's look at range it ;rather than defining the range explicity I'd like to read the selection in Excel and use it ;need a function like _Excel_SelectionRead ;try hacking Excel.au3 _Excel_RangeRead to see if can create _Excel_SelectionRead looks like .Selection .Value .Text and .Address possible MsgBox($MB_SYSTEMMODAL, "Info", "Select cells in Excel then click OK") ;ACTUALLY get range of the selection and this will suffice for us to use on the $aExcelArray $vRange = $oWorkbook.ActiveSheet.Selection.Address($vRange) ;tried all sorts of permutations and clearly I need help _DebugArrayDisplay($vRange, $vRange) ;let's look at range it ;$vResult = $oExcel.Transpose($vRange.Value) ;_DebugArrayDisplay($vResult, $vResult) ;let's look at range it _Excel_Close($oExcel, False, True) Exit  
    • By therks
      So I'm needing a (better) way to get the selection in an edit control, while knowing which end of the selection is active vs anchor (ie, if you're holding shift while moving with the arrow keys, which end of the selection is moving and which is not). Since _GUICtrlEdit_GetSel() only returns the start and end positions, in the order of smallest to largest, if you were to pass that back to the _GUICtrlEdit_SetSel(), the user's selection could end up "backwards".
      My solution has been this function:
      Func _GUICtrlEdit_GetSelByAnchor($hWnd) ; Get selection range with anchor in first index If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) Local $aActive, $aSelection = _GUICtrlEdit_GetSel($hWnd) ; Get base selection If $aSelection[0] <> $aSelection[1] Then ; Only proceed if actual selection range _GUICtrlEdit_SetSel($hWnd, -1, 0) ; Deselect, leaving only the active point $aActive = _GUICtrlEdit_GetSel($hWnd) ; Record the active point If $aActive[0] = $aSelection[0] Then ; If the active point is equal to the original first index ; Swap the original selection points (putting the anchor in [0] and active in [1]) $aSelection[0] = $aSelection[1] $aSelection[1] = $aActive[0] EndIf _GUICtrlEdit_SetSel($hWnd, $aSelection[0], $aSelection[1]) ; Reset selection to the original points EndIf Return $aSelection EndFunc The problem with this, as you may have already guessed from the two SetSel calls, is that calling it in a tight loop causes a lot of flickering. Is there a better, more reliable way to do what I'm looking for?
×
×
  • Create New...