Jump to content

Partial transparency [SOLVED]


Recommended Posts

Quick Details:

Below is a function I grabbed somewhere on the forums (slightly modified). It's basic purpose is to create a 'selection tool' that allows you to select a portion of the screen, much like the rectangle selection on the Desktop, only I've utilized this function to capture screen-shots... ;)

My Question:

How would I got about 'darking-out' the screen, except for that is being selected? So that the selection tool kinda acts like a highlighter... It would give a user a better idea and better focus on what exactly they are selecting. :evil:

Func Mark_Rect()
    Local $hPM = WinGetHandle("[CLASS:Progman]")
    Local $vSize = WinGetClientSize($hPM)
    Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
    Local $UserDLL = DllOpen("user32.dll")

    ; Create transparent GUI with Cross cursor
    $hCross_GUI = GUICreate("Test", $vSize[0], $vSize[1], 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
    WinSetTrans($hCross_GUI, "", 1)
    GUISetState(@SW_SHOW, $hCross_GUI)
    GUISetCursor(3, 1, $hCross_GUI)

    Global $hRectangle_GUI = GUICreate("", $vSize[0], $vSize[1], 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    GUISetBkColor(0x000000)
    
    ; Wait until mouse button pressed
    While Not _IsPressed("01", $UserDLL)
        Sleep(10)
    WEnd

    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]

    ; Draw rectangle while mouse button pressed
    While _IsPressed("01", $UserDLL)

        $aMouse_Pos = MouseGetPos()

        $hMaster_Mask = _WinAPI_CreateRectRgn(0, 0, 0, 0)
        $hMask = _WinAPI_CreateRectRgn($iX1, $aMouse_Pos[1], $aMouse_Pos[0], $aMouse_Pos[1] + 1); Bottom of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        $hMask = _WinAPI_CreateRectRgn($iX1, $iY1, $iX1 + 1, $aMouse_Pos[1]); Left of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        $hMask = _WinAPI_CreateRectRgn($iX1 + 1, $iY1 + 1, $aMouse_Pos[0], $iY1); Top of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        $hMask = _WinAPI_CreateRectRgn($aMouse_Pos[0], $iY1, $aMouse_Pos[0] + 1, $aMouse_Pos[1]); Right of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        ; Set overall region
        _WinAPI_SetWindowRgn($hRectangle_GUI, $hMaster_Mask)

        If WinGetState($hRectangle_GUI) < 15 Then GUISetState(@SW_SHOW,$hRectangle_GUI)
        Sleep(10)

    WEnd

    ; Get second mouse position
    $iX2 = $aMouse_Pos[0]
    $iY2 = $aMouse_Pos[1]

    ; Set in correct order if required
    If $iX2 < $iX1 Then
        $iTemp = $iX1
        $iX1 = $iX2
        $iX2 = $iTemp
    EndIf
    If $iY2 < $iY1 Then
        $iTemp = $iY1
        $iY1 = $iY2
        $iY2 = $iTemp
    EndIf

    GUIDelete($hRectangle_GUI)
    GUIDelete($hCross_GUI)
    DllClose($UserDLL)
    Dim $aRect[5]
    $aRect[1] = $iX1
    $aRect[2] = $iY1
    $aRect[3] = $iX2
    $aRect[4] = $iY2
    If $iX1 = $iX2 And $iY1 = $iY2 Then
        TrayTip("Canceled", "No selection...", 25)
        Return 0
    Else
        Return $aRect
    EndIf


EndFunc ;==>Mark_Rect
Edited by BinaryBrother

SIGNATURE_0X800007D NOT FOUND

Link to comment
Share on other sites

#include <GDIP.au3>
#include <Misc.au3>
#include <ScreenCapture.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

$aRect = Mark_Rect()

If IsArray($aRect) Then
    _GDIPlus_Startup()
    
    $hGUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP)
    $hBmp = _ScreenCapture_Capture("", 0, 0, -1, -1, False)
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
    _WinAPI_DeleteObject($hBmp)
    
    $iX = $aRect[1]
    $iY = $aRect[2]
    $iWidth = $aRect[3]-$iX
    $iHeight = $aRect[4]-$iY
    
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hSelectBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    $hContext = _GDIPlus_ImageGetGraphicsContext($hSelectBitmap)
    _GDIPlus_GraphicsDrawImageRectRect($hContext, $hBitmap, $iX, $iY, $iWidth, $iHeight, 0, 0, $iWidth, $iHeight)
    _GDIPlus_GraphicsDispose($hContext)
    
    $nBrightness = -0.5
    
    $hIA = _GDIPlus_ImageAttributesCreate()
    $tColorMatrix = _GDIPlus_ColorMatrixCreate()
    $pColorMatrix = DllStructGetPtr($tColorMatrix)
    _GDIPlus_ColorMatrixTranslate($tColorMatrix, $nBrightness, $nBrightness, $nBrightness, 0, 1)
    _GDIPlus_ImageAttributesSetColorMatrix($hIA, 1, True, $pColorMatrix)
    
    $aSize = _GDIPlus_ImageGetDimension($hBitmap)
    $iDeskWidth = $aSize[0]
    $iDeskHeight = $aSize[1]
    
    $hBitmapDesk = _GDIPlus_BitmapCreateFromGraphics($iDeskWidth, $iDeskHeight, $hGraphics)
    $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmapDesk)  
    
    _GDIPlus_GraphicsDrawImageRectRectIA($hContext, $hBitmap, 0, 0, $iDeskWidth, $iDeskHeight, 0, 0, $iDeskWidth, $iDeskHeight, $hIA)
    _GDIPlus_GraphicsDrawImageRectRect($hContext, $hSelectBitmap, 0, 0, $iWidth, $iHeight, $iX, $iY, $iWidth, $iHeight)
    
    _GDIPlus_GraphicsDispose($hContext)
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_BitmapDispose($hSelectBitmap)

    GUISetState()
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmapDesk, 0, 0)
    
    Do
    Until GUIGetMsg() = -3
    
    _GDIPlus_GraphicsDispose($hGraphics)
    GUIDelete()
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()
    
EndIf

Func Mark_Rect()
    Local $hPM = WinGetHandle("[CLASS:Progman]")
    Local $vSize = WinGetClientSize($hPM)
    Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
    Local $UserDLL = DllOpen("user32.dll")

    ; Create transparent GUI with Cross cursor
    $hCross_GUI = GUICreate("Test", $vSize[0], $vSize[1], 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
    WinSetTrans($hCross_GUI, "", 1)
    GUISetState(@SW_SHOW, $hCross_GUI)
    GUISetCursor(3, 1, $hCross_GUI)

    Global $hRectangle_GUI = GUICreate("", $vSize[0], $vSize[1], 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    GUISetBkColor(0x000000)
    
    ; Wait until mouse button pressed
    While Not _IsPressed("01", $UserDLL)
        Sleep(10)
    WEnd

    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]

    ; Draw rectangle while mouse button pressed
    While _IsPressed("01", $UserDLL)

        $aMouse_Pos = MouseGetPos()

        $hMaster_Mask = _WinAPI_CreateRectRgn(0, 0, 0, 0)
        $hMask = _WinAPI_CreateRectRgn($iX1, $aMouse_Pos[1], $aMouse_Pos[0], $aMouse_Pos[1] + 1); Bottom of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        $hMask = _WinAPI_CreateRectRgn($iX1, $iY1, $iX1 + 1, $aMouse_Pos[1]); Left of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        $hMask = _WinAPI_CreateRectRgn($iX1 + 1, $iY1 + 1, $aMouse_Pos[0], $iY1); Top of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        $hMask = _WinAPI_CreateRectRgn($aMouse_Pos[0], $iY1, $aMouse_Pos[0] + 1, $aMouse_Pos[1]); Right of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        ; Set overall region
        _WinAPI_SetWindowRgn($hRectangle_GUI, $hMaster_Mask)

        If WinGetState($hRectangle_GUI) < 15 Then GUISetState(@SW_SHOW,$hRectangle_GUI)
        Sleep(10)

    WEnd

    ; Get second mouse position
    $iX2 = $aMouse_Pos[0]
    $iY2 = $aMouse_Pos[1]

    ; Set in correct order if required
    If $iX2 < $iX1 Then
        $iTemp = $iX1
        $iX1 = $iX2
        $iX2 = $iTemp
    EndIf
    If $iY2 < $iY1 Then
        $iTemp = $iY1
        $iY1 = $iY2
        $iY2 = $iTemp
    EndIf

    GUIDelete($hRectangle_GUI)
    GUIDelete($hCross_GUI)
    DllClose($UserDLL)
    Dim $aRect[5]
    $aRect[1] = $iX1
    $aRect[2] = $iY1
    $aRect[3] = $iX2
    $aRect[4] = $iY2
    If $iX1 = $iX2 And $iY1 = $iY2 Then
        TrayTip("Canceled", "No selection...", 25)
        Return 0
    Else
        Return $aRect
    EndIf


EndFunc ;==>Mark_Rect

Link to comment
Share on other sites

Wow, that is really nice Auth. ;)

While that is exactly the effect I was looking for, I was wanting to do it 'live', while the user was making the selection. I'll play with your code a bit, and see if I can pull it off. Based on the screen flash, I'll assume the redraw isn't going to play nice when put into a loop, but I'll mess with it and see if it works. :evil:

SIGNATURE_0X800007D NOT FOUND

Link to comment
Share on other sites

  • Moderators

BinaryBrother,

This script does not highlight the selected area, but does put a rectangle around it:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <ScreenCapture.au3>
#Include <Misc.au3>

Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path

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

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

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $hCancel_Button
            FileDelete(@ScriptDir & "\Rect.bmp")
            Exit
        Case $hRect_Button
            GUISetState(@SW_HIDE, $hMain_GUI)
            Mark_Rect()
            ; Capture selected area
            $sBMP_Path = @ScriptDir & "\Rect.bmp"
            _ScreenCapture_Capture($sBMP_Path, $iX1, $iY1, $iX2, $iY2, False)
            GUISetState(@SW_SHOW, $hMain_GUI)
            ; Display image
            $hBitmap_GUI = GUICreate("Selected Rectangle", $iX2 - $iX1 + 1, $iY2 - $iY1 + 1, 100, 100)
            $hPic = GUICtrlCreatePic(@ScriptDir & "\Rect.bmp", 0, 0, $iX2 - $iX1 + 1, $iY2 - $iY1 + 1)
            GUISetState()

    EndSwitch

WEnd

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

Func Mark_Rect()

    Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
    Local $UserDLL = DllOpen("user32.dll")

    ; Create transparent GUI with Cross cursor
    $hCross_GUI = GUICreate("Test", @DesktopWidth, @DesktopHeight - 20, 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
    WinSetTrans($hCross_GUI, "", 8)
    GUISetState(@SW_SHOW, $hCross_GUI)
    GUISetCursor(3, 1, $hCross_GUI)

    Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    GUISetBkColor(0x000000)

    ; Wait until mouse button pressed
    While Not _IsPressed("01", $UserDLL)
        Sleep(10)
    WEnd

    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]

    ; Draw rectangle while mouse button pressed
    While _IsPressed("01", $UserDLL)

        $aMouse_Pos = MouseGetPos()

        $hMaster_Mask = _WinAPI_CreateRectRgn(0, 0, 0, 0)
        $hMask = _WinAPI_CreateRectRgn($iX1,  $aMouse_Pos[1], $aMouse_Pos[0],  $aMouse_Pos[1] + 1) ; Bottom of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        $hMask = _WinAPI_CreateRectRgn($iX1, $iY1, $iX1 + 1, $aMouse_Pos[1]) ; Left of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        $hMask = _WinAPI_CreateRectRgn($iX1 + 1, $iY1 + 1, $aMouse_Pos[0], $iY1) ; Top of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        $hMask = _WinAPI_CreateRectRgn($aMouse_Pos[0], $iY1, $aMouse_Pos[0] + 1,  $aMouse_Pos[1]) ; Right of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        ; Set overall region
        _WinAPI_SetWindowRgn($hRectangle_GUI, $hMaster_Mask)

        If WinGetState($hRectangle_GUI) < 15 Then GUISetState()
        Sleep(10)

    WEnd

    ; Get second mouse position
    $iX2 = $aMouse_Pos[0]
    $iY2 = $aMouse_Pos[1]

    ; Set in correct order if required
    If $iX2 < $iX1 Then
        $iTemp = $iX1
        $iX1 = $iX2
        $iX2 = $iTemp
    EndIf
    If $iY2 < $iY1 Then
        $iTemp = $iY1
        $iY1 = $iY2
        $iY2 = $iTemp
    EndIf

    GUIDelete($hRectangle_GUI)
    GUIDelete($hCross_GUI)
    DllClose($UserDLL)

EndFunc   ;==>Mark_Rect

Perhaps it might help?

M23

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

 

Link to comment
Share on other sites

#include <GDIP.au3>
#include <Misc.au3>
#include <ScreenCapture.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

_Test()

Func _Test()
    _GDIPlus_Startup()
 
    Local $hPM = WinGetHandle("[CLASS:Progman]")
    Local $vSize = WinGetClientSize($hPM)
    Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
    Local $UserDLL = DllOpen("user32.dll")
    
    $hBmp = _ScreenCapture_Capture("", 0, 0, $vSize[0], $vSize[1], False)
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
    _WinAPI_DeleteObject($hBmp)

    $hGUI = GUICreate("", $vSize[0], $vSize[1], 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
    GUISetState(@SW_SHOW, $hGUI)
    GUISetCursor(3, 1, $hGUI)

    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    $nBrightness = -0.5

    $hIA = _GDIPlus_ImageAttributesCreate()
    $tColorMatrix = _GDIPlus_ColorMatrixCreate()
    $pColorMatrix = DllStructGetPtr($tColorMatrix)
    _GDIPlus_ColorMatrixTranslate($tColorMatrix, $nBrightness, $nBrightness, $nBrightness, 0, 1)
    _GDIPlus_ImageAttributesSetColorMatrix($hIA, 1, True, $pColorMatrix)

    $hBitmapDesk = _GDIPlus_BitmapCreateFromGraphics($vSize[0], $vSize[1], $hGraphics)
    $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmapDesk)  

    _GDIPlus_GraphicsDrawImageRectRectIA($hContext, $hBitmap, 0, 0, $vSize[0], $vSize[1], 0, 0, $vSize[0], $vSize[1], $hIA)
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmapDesk, 0, 0, $vSize[0], $vSize[1])

    ; Wait until mouse button pressed
    While Not _IsPressed("01", $UserDLL)
        Sleep(20)
    WEnd

     $aMouse_Pos = MouseGetPos()
    $iX = $aMouse_Pos[0]
    $iY = $aMouse_Pos[1]


    ; Draw rectangle while mouse button pressed
    While _IsPressed("01", $UserDLL)

        $aMouse_Pos = MouseGetPos()

        If $iX < $aMouse_Pos[0] Then
            $iX1 = $iX
            $iX2 = $aMouse_Pos[0]
        Else
            $iX1 = $aMouse_Pos[0]
            $iX2 = $iX
        EndIf
        
        If $iY < $aMouse_Pos[1] Then
            $iY1 = $iY
            $iY2 = $aMouse_Pos[1]
        Else
            $iY1 = $aMouse_Pos[1]
            $iY2 = $iY
        EndIf
        
        $iWidth = $iX2-$iX1
        $iHeight = $iY2-$iY1
        _GDIPlus_GraphicsDrawImageRectRectIA($hContext, $hBitmap, 0, 0, $vSize[0], $vSize[1], 0, 0, $vSize[0], $vSize[1], $hIA)
        
        If $iHeight <> 0 And $iWidth <> 0 Then _
            _GDIPlus_GraphicsDrawImageRectRect($hContext, $hBitmap, $iX1, $iY1, $iWidth, $iHeight, $iX1, $iY1, $iWidth, $iHeight)
            
        _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmapDesk, 0, 0, $vSize[0], $vSize[1])
    WEnd

    _GDIPlus_GraphicsDispose($hContext)
    _GDIPlus_BitmapDispose($hBitmapDesk)
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_BitmapDispose($hBitmap)

    GUIDelete($hGUI)
    DllClose($UserDLL)
    _GDIPlus_Shutdown()

    Dim $aRect[5]
    $aRect[1] = $iX1
    $aRect[2] = $iY1
    $aRect[3] = $iX2
    $aRect[4] = $iY2

    If $iHeight <> 0 And $iWidth <> 0 Then
        Return $aRect
    Else
        TrayTip("Canceled", "No selection...", 25)
        Return 0
    EndIf
EndFunc

Link to comment
Share on other sites

Auth nailed it right on the head... :evil:

Your brain is much appreciated.

@Melba23

Thanks for your input, I understand what Auth's first example was doing (mostly) and was simply trying to achieve a live implementation. A lot of the newer screen-capturing utilities dark-out the rest of the screen, except for what is being selected for the screen-shot. I'm trying to make a pretty cool one to compete with Jing feature-wise... ;)

SIGNATURE_0X800007D NOT FOUND

Link to comment
Share on other sites

  • Moderators

BinaryBrother,

Here is my version of the "Highlighted" area selection:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <ScreenCapture.au3>
#Include <Misc.au3>

Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path

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

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

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $hCancel_Button
            FileDelete(@ScriptDir & "\Rect.bmp")
            Exit
        Case $hRect_Button
            GUISetState(@SW_HIDE, $hMain_GUI)
            Mark_Rect()
            ; Capture selected area
            $sBMP_Path = @ScriptDir & "\Rect.bmp"
            _ScreenCapture_Capture($sBMP_Path, $iX1, $iY1, $iX2, $iY2, False)
            GUISetState(@SW_SHOW, $hMain_GUI)
            ; Display image
            $hBitmap_GUI = GUICreate("Selected Rectangle", $iX2 - $iX1 + 1, $iY2 - $iY1 + 1, 100, 100)
            $hPic = GUICtrlCreatePic(@ScriptDir & "\Rect.bmp", 0, 0, $iX2 - $iX1 + 1, $iY2 - $iY1 + 1)
            GUISetState()

    EndSwitch

WEnd

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

Func Mark_Rect()

    Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
    Local $UserDLL = DllOpen("user32.dll")

    Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    _GUICreateInvRect($hRectangle_GUI, 0, 0, 1, 1)
    GUISetBkColor(0)
    WinSetTrans($hRectangle_GUI, "", 50)
    GUISetState(@SW_SHOW, $hRectangle_GUI)
    GUISetCursor(3, 1, $hRectangle_GUI)

    ; Wait until mouse button pressed
    While Not _IsPressed("01", $UserDLL)
        Sleep(10)
    WEnd

    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]

    ; Draw rectangle while mouse button pressed
    While _IsPressed("01", $UserDLL)

        $aMouse_Pos = MouseGetPos()

        ; Set in correct order if required
        If $aMouse_Pos[0] < $iX1 Then
            $iX_Pos = $aMouse_Pos[0]
            $iWidth = $iX1 - $aMouse_Pos[0]
        Else
            $iX_Pos = $iX1
            $iWidth = $aMouse_Pos[0] - $iX1
        EndIf
        If $aMouse_Pos[1] < $iY1 Then
            $iY_Pos = $aMouse_Pos[1]
            $iHeight = $iY1 - $aMouse_Pos[1]
        Else
            $iY_Pos = $iY1
            $iHeight = $aMouse_Pos[1] - $iY1
        EndIf

        _GUICreateInvRect($hRectangle_GUI, $iX_Pos, $iY_Pos, $iWidth, $iHeight)

        Sleep(10)

    WEnd

    ; Get second mouse position
    $iX2 = $aMouse_Pos[0]
    $iY2 = $aMouse_Pos[1]

    ; Set in correct order if required
    If $iX2 < $iX1 Then
        $iTemp = $iX1
        $iX1 = $iX2
        $iX2 = $iTemp
    EndIf
    If $iY2 < $iY1 Then
        $iTemp = $iY1
        $iY1 = $iY2
        $iY2 = $iTemp
    EndIf

    GUIDelete($hRectangle_GUI)
    DllClose($UserDLL)

EndFunc   ;==>Mark_Rect

Func _GUICreateInvRect($hWnd, $iX, $iY, $iW, $iH)

    $hMask_1 = _WinAPI_CreateRectRgn(0, 0, @DesktopWidth, $iY)
    $hMask_2 = _WinAPI_CreateRectRgn(0, 0, $iX, @DesktopHeight)
    $hMask_3 = _WinAPI_CreateRectRgn($iX + $iW, 0, @DesktopWidth, @DesktopHeight)
    $hMask_4 = _WinAPI_CreateRectRgn(0, $iY + $iH, @DesktopWidth, @DesktopHeight)

    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_2, 2)
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_3, 2)
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_4, 2)

    _WinAPI_DeleteObject($hMask_2)
    _WinAPI_DeleteObject($hMask_3)
    _WinAPI_DeleteObject($hMask_4)

    _WinAPI_SetWindowRgn($hWnd, $hMask_1, 1)

EndFunc

Just to offer an alternative solution without too much GDI. ;)

Hope someone finds it useful.

M23

Edit: Small code change to add a + cursor

Edit 2: Needed to delete the combined masks to prevent memory leakage.

Edited by Melba23

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

 

Link to comment
Share on other sites

Wow... Nice work Melba23! That's a tad faster than Auth's example as well. :evil:

You guys are geniuses! Thanks for the code, I really appreciate it. :idea:

If either of you guys would like to see how I put this to use, here is what I done with it... ;)

http://www.binarybrother.com/?page_id=9

The source isn't available just yet, although I'm sure either of you could come up with something much better in half the time...

Credits to:

JamesBrooks (Aero Functions)

Authenticity & Melba23 (Screen darkening effect)

Yashied (FTP UDF)

Others (Various forum posts)

P.S. I would let either of you see the source if you actually wanted it... :evil:

Edited by BinaryBrother

SIGNATURE_0X800007D NOT FOUND

Link to comment
Share on other sites

Here is one that overlays the desktop and as such does not require screencaptures. The desktop operations continue as normal.

I've taken it from this topic and modified it: http://www.autoitscript.com/forum/index.php?showtopic=12464

I didn't have time to do the actual selection with mouse, so you'll have to do that yourself.

#include <GuiConstants.au3>

$my_gui = GUICreate("MyGUI", @DesktopWidth + 10, @DesktopHeight + 10)
GUISetBkColor(0) ; Make it black
WinSetOnTop($my_gui, "", 1) ; Put it on top
WinSetTrans($my_gui, "", 30)

GUISetState()

_GuiHole($my_gui, 300, 300, 400, 300)

While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
        Case Else
            ;;;
    EndSelect
WEnd
Exit


Func _GuiHole($h_win, $i_x, $i_y, $i_size_w, $i_size_h)
    Dim $pos, $outer_rgn, $inner_rgn, $wh, $combined_rgn, $ret
    $pos = WinGetPos($h_win)

    $outer_rgn = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", $pos[2], "long", $pos[3])
    If IsArray($outer_rgn) Then
        $inner_rgn = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $i_x, "long", $i_y, "long", $i_x + $i_size_w, "long", $i_y + $i_size_h)
        If IsArray($inner_rgn) Then
            $combined_rgn = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 0, "long", 0)
            If IsArray($combined_rgn) Then
                DllCall("gdi32.dll", "long", "CombineRgn", "long", $combined_rgn[0], "long", $outer_rgn[0], "long", $inner_rgn[0], "int", 4)
                $ret = DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $h_win, "long", $combined_rgn[0], "int", 1)
                If $ret[0] Then
                    Return 1
                Else
                    Return 0
                EndIf
            Else
                Return 0
            EndIf
        Else
            Return 0
        EndIf
    Else
        Return 0
    EndIf

EndFunc   ;==>_GuiHole
Link to comment
Share on other sites

I've seen that GUI-hole trick around before, and forgot all about it. Nice find Manadar!

I've believe I have more than enough examples to get done what I needed, so I'm going to mark this as solved with 3 awesome alternative views.

@Auth, Melba23, Manadar

Thanks guys. ;)

SIGNATURE_0X800007D NOT FOUND

Link to comment
Share on other sites

  • 2 months later...

@Melba23

This is great. I was trying this out on a number of desktops with dark/black backgrounds - as such, the selection area is a little hard to see / the highlight effect is lost a little. Is it possible to draw a coloured/white rectangle around the area - i tries to merge elements from both your examples and entered flicker hell... I don't understand any of the WinAPI calls...

TIA :mellow:

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...