Rubber Band Rectangle Screen Selection

Example scripts and tips (replaces Old Scripts & Tips archive)

Moderators: Dorian (MJT support), JRL, Phil Pendlebury

Post Reply
User avatar
JRL
Automation Wizard
Posts: 3497
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Rubber Band Rectangle Screen Selection

Post by JRL » Sun May 04, 2014 6:22 am

In 2007 I posted a script to draw a rubber band section rectangle. The first posts in the thread used a dialog that resized as you moved the mouse. The final post used Window's MoveToEx and LineTo APIs to draw lines on the screen. This is pretty much the same method as that last post except this one is updated to use version 12 style dialogs. Way simpler code. To learn how this script works, read the remarks.

Code: Select all

/*=========================================
44 lines of code (excluding the MessageModal and Exit)
Rubber Band Selection Rectangle by Dick Lockey
May 4, 2014
===========================================
*/

//Code provided by Marcus for acquiring the virtual screen size
Let>SM_CXVIRTUALSCREEN=78
Let>SM_CYVIRTUALSCREEN=79
Let>SM_XVIRTUALSCREEN=76
Let>SM_YVIRTUALSCREEN=77
LibFunc>User32,GetSystemMetrics,VScrWidth,SM_CXVIRTUALSCREEN
LibFunc>User32,GetSystemMetrics,VScrHeight,SM_CYVIRTUALSCREEN
LibFunc>User32,GetSystemMetrics,VScrLeft,SM_XVIRTUALSCREEN
LibFunc>User32,GetSystemMetrics,VScrTop,SM_YVIRTUALSCREEN

//Minimal dialog specifications no border and set alphablend to 100
Dialog>RubberBandSelectionDialog
object RubberBandSelectionDialog: TForm
  BorderStyle = bsNone
  AlphaBlend = True
  AlphaBlendValue = 100
end
EndDialog>RubberBandSelectionDialog

//Dialog actions for mouse down and mouse up
AddDialogHandler>RubberBandSelectionDialog,,OnMouseDown,DrawSelection
AddDialogHandler>RubberBandSelectionDialog,,OnMouseUp,EndDrawSelection
//Set the dialog window to cover the virtual screen area
Let>WIN_USEHANDLE=1
  ResizeWindow>RubberBandSelectionDialog.handle,VScrWidth,VScrHeight
  MoveWindow>RubberBandSelectionDialog.handle,VScrLeft,VScrTop
Let>WIN_USEHANDLE=0
//Flag variable to allow jump from mouse down subroutine when the script is not
//artificailly aborted in the mouse up subroutine.
Let>DrawFlag=1
//Display the semi transparent dialog
Show>RubberBandSelectionDialog,

//MouseDown subroutine
SRT>DrawSelection
  //Get the cursor position on mouse down.
  GetCursorPos>StartX,StartY
  //Get a handle to a Device Context (HDC) of the semi transparent dialog
  //The HDC is required so the dialog can have lines drawn on it.
  LibFunc>user32,GetDC,HDC,RubberBandSelectionDialog.handle
  //Set up the first draw from point.
  Libfunc>gdi32,MoveToEx,mtres,HDC,StartX,StartY,0
  //Label to loop to redraw selection rectangle for each new mouse position
  Label>Draw
    //Change the dialog color imperceptably (by 1 color number)
    //This is the best method I've been able to come up with for
    //refreshing the dialog, thus erasing the last selection rectangle
    //prior to the next rectangle being drawn.
    SetDialogProperty>RubberBandSelectionDialog,,Color,16777201
    SetDialogProperty>RubberBandSelectionDialog,,Color,16777200
    //Get the next mouse cursor position for the next selection rectangle draw
    GetCursorPos>CurX,CurY
    //Draw the next selection rectangle
    Libfunc>gdi32,LineTo,ltres,HDC,StartX,CurY
	Libfunc>gdi32,LineTo,ltres,HDC,CurX,CurY
	Libfunc>gdi32,LineTo,ltres,HDC,CurX,StartY
	Libfunc>gdi32,LineTo,ltres,HDC,StartX,StartY
    //Wait for a tenth of a second
    Wait>0.1
  //Test the flag variable to see if the mouse button has been
  //released and we can stop redrawing the selection rectangle.
  If>DrawFlag=1,Draw
END>DrawSelection

//MouseUp subroutine
SRT>EndDrawSelection
  //Set flag variable to zero to jump out of mouse down subroutine.
  Let>DrawFlag=0
  //Get the cursor position on mouse up.
  GetCursorPos>UpX,UpY
  //Make the semi transparent dialog invisible.
  SetDialogProperty>RubberBandSelectionDialog,,Visible,False
  //Clear the Device Context handle for the semi transparent dialog.
  LibFunc>user32,ReleaseDC,RDCres,HDC_1,HDC
  //Display the mouse selections in lieu of making any actual
  //use of the up and down mouse coordinates.
  MDL>Start X = %StartX%%crlf%Start Y = %StartY%%crlf%End X = %UpX%%crlf%End Y = %UpY%
  Exit>0
END>EndDrawSelection
The following script uses the selection to place a .PNG file of the selection in the temp folder.

Code: Select all

/*=========================================
44 lines of code (excluding the MessageModal and Exit)
Rubber Band Selection Rectangle by Dick Lockey
May 4, 2014
===========================================
*/
//Code provided by Marcus for acquiring the virtual screen size
Let>SM_CXVIRTUALSCREEN=78
Let>SM_CYVIRTUALSCREEN=79
Let>SM_XVIRTUALSCREEN=76
Let>SM_YVIRTUALSCREEN=77
LibFunc>User32,GetSystemMetrics,VScrWidth,SM_CXVIRTUALSCREEN
LibFunc>User32,GetSystemMetrics,VScrHeight,SM_CYVIRTUALSCREEN
LibFunc>User32,GetSystemMetrics,VScrLeft,SM_XVIRTUALSCREEN
LibFunc>User32,GetSystemMetrics,VScrTop,SM_YVIRTUALSCREEN
//Minimal dialog specifications no border and set alphablend to 100
Dialog>RubberBandSelectionDialog
object RubberBandSelectionDialog: TForm
  BorderStyle = bsNone
  AlphaBlend = True
  AlphaBlendValue = 100
end
EndDialog>RubberBandSelectionDialog
//Dialog actions for mouse down and mouse up
AddDialogHandler>RubberBandSelectionDialog,,OnMouseDown,DrawSelection
AddDialogHandler>RubberBandSelectionDialog,,OnMouseUp,EndDrawSelection
//Set the dialog window to cover the virtual screen area
Let>WIN_USEHANDLE=1
  ResizeWindow>RubberBandSelectionDialog.handle,VScrWidth,VScrHeight
  MoveWindow>RubberBandSelectionDialog.handle,VScrLeft,VScrTop
Let>WIN_USEHANDLE=0
//Flag variable to allow jump from mouse down subroutine when the script is not
//artificially aborted in the mouse up subroutine.
Let>DrawFlag=1
//Display the semi transparent dialog
Show>RubberBandSelectionDialog,
//MouseDown subroutine
SRT>DrawSelection
  //Get the cursor position on mouse down.
  GetCursorPos>StartX,StartY
  //Get a handle to a Device Context (HDC) of the semi transparent dialog
  //The HDC is required so the dialog can have lines drawn on it.
  LibFunc>user32,GetDC,HDC,RubberBandSelectionDialog.handle
  //Set up the first draw from point.
  Libfunc>gdi32,MoveToEx,mtres,HDC,StartX,StartY,0
  //Label to loop to redraw selection rectangle for each new mouse position
  Label>Draw
    //Change the dialog color imperceptably (by 1 color number)
    //This is the best method I've been able to come up with for
    //refreshing the dialog, thus erasing the last selection rectangle
    //prior to the next rectangle being drawn.
    SetDialogProperty>RubberBandSelectionDialog,,Color,16777201
    SetDialogProperty>RubberBandSelectionDialog,,Color,16777200
    //Get the next mouse cursor position for the next selection rectangle draw
    GetCursorPos>CurX,CurY
    //Draw the next selection rectangle
    Libfunc>gdi32,LineTo,ltres,HDC,StartX,CurY
    Libfunc>gdi32,LineTo,ltres,HDC,CurX,CurY
    Libfunc>gdi32,LineTo,ltres,HDC,CurX,StartY
    Libfunc>gdi32,LineTo,ltres,HDC,StartX,StartY
    //Wait for a tenth of a second
    Wait>0.1
  //Test the flag variable to see if the mouse button has been
  //released and we can stop redrawing the selection rectangle.
  If>DrawFlag=1,Draw
END>DrawSelection
//MouseUp subroutine
SRT>EndDrawSelection
  //Set flag variable to zero to jump out of mouse down subroutine.
  Let>DrawFlag=0
  //Get the cursor position on mouse up.
  GetCursorPos>UpX,UpY
  //Make the semi transparent dialog invisible.
  SetDialogProperty>RubberBandSelectionDialog,,Visible,False
  //Clear the Device Context handle for the semi transparent dialog.
  LibFunc>user32,ReleaseDC,RDCres,HDC_1,HDC
/*
  //Display the mouse selections in lieu of making any actual
  //use of the up and down mouse coordinates.
  MDL>Start X = %StartX%%crlf%Start Y = %StartY%%crlf%End X = %UpX%%crlf%End Y = %UpY%
*/
  //Use the coordinates to select a portion of the screen as a png file.
  If>%StartX%>%UpX%
    Let>ULX=%UPX%
    Let>LRX=%StartX%
  Else
    Let>ULX=%StartX%
    Let>LRX=%UPX%
  EndIf
  If>%StartY%>%UpY%
    Let>ULY=%UPY%
    Let>LRY=%StartY%
  Else
    Let>ULY=%StartY%
    Let>LRY=%UPY%
  EndIf
  ScreenCapture>ULX,ULY,LRX,LRY,%temp_dir%ScreenCap.png
  Exit>0
END>EndDrawSelection

Post Reply
Sign up to our newsletter for free automation tips, tricks & discounts