Jump to content

Drawing on a ScreenCapture


Wombat
 Share

Recommended Posts

Alright so I have this script that I pulled from the depths of the forum, Melba23 was the author of the original code. I changed it to meet my requirements (thank you Melba23)

 

I now wish to add the functionality of being able to draw on the image, as well as being able to save the edited file. Where do I start, I've scavenged, dug around and can't find any examples that help.

 

I'm looking for the simplest way to do this, I know I can use GDI, but I would like to avoid that if possible.

 

Anywho, here is the code:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
#include <StaticConstants.au3>
#include <File.au3>
#include <Array.au3>

Opt("GUIOnEventMode", 1)

Global Const $SYSTEMROOT = EnvGet('systemdrive')
Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path, $dc
Global $editValue = False



; Create GUI
$hMain_GUI = GUICreate("Select Rectangle", 400, 50)
GUISetOnEvent($GUI_EVENT_CLOSE, "mGUI_Close", "Select Rectangle")

$hRect_Button = GUICtrlCreateButton("Capture", 10, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Capture")
$hCancel_Button = GUICtrlCreateButton("Cancel", 310, 10, 80, 30)
GUICtrlSetOnEvent(-1, "mGUI_Close")
$hEdit_Button = GUICtrlCreateButton("Edit", 110, 10, 80, 30)
GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
GUICtrlSetOnEvent(-1, "_Edit")
$hSave_Button = GUICtrlCreateButton("Save", 210, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Save")
GUICtrlSetState($hSave_Button, $GUI_DISABLE)

GUISetState()

While 1

    Sleep(10)
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, "", 75)
    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   ;==>_GUICreateInvRect

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

Func _Capture()
    If WinExists("Captured Image", "") = 1 Then GUIDelete("Captured Image")
    FileDelete(@ScriptDir & "\temp.jpg")
    GUISetState(@SW_HIDE, $hMain_GUI)
    Mark_Rect()
    ; Capture selected area
    $sBMP_Path = @ScriptDir & "\temp.jpg"
    _ScreenCapture_Capture($sBMP_Path, $iX1, $iY1, $iX2, $iY2, False)
    GUISetState(@SW_SHOW, $hMain_GUI)
    WinMove("Select Rectangle", "", Default + 75, Default + 100)
    GUICtrlSetState($hSave_Button, $GUI_ENABLE)
    GUICtrlSetState($hEdit_Button, $GUI_ENABLE)
    ; Display image
    $hBitmap_GUI = GUICreate("Captured Image", $iX2 - $iX1 + 50, $iY2 - $iY1 + 50, Default, Default)
    GUISetBkColor(0x525252, "Captured Image")
    GUISetOnEvent($GUI_EVENT_CLOSE, "cGUI_Close", "Captured Image")
    $hPic = GUICtrlCreatePic(@ScriptDir & "\temp.jpg", 25, 25, $iX2 - $iX1 + 1, $iY2 - $iY1 + 1)
    GUISetState()
EndFunc   ;==>_Capture

Func _Edit()
    If $editValue=False Then
        $editValue=True
        GUICtrlSetData($hEdit_Button, "Stop")
    ElseIf $editValue=True Then
        $editValue=False
        GUICtrlSetData($hEdit_Button, "Edit")
    EndIf
EndFunc   ;==>_Edit

Func _Save()
    Local $scPath = @DocumentsCommonDir & "\MyScreenCaptures\"
    If Not FileExists($scPath) Then DirCreate($scPath)
    Local $savePath = FileSaveDialog("Save your screen capture", $scPath, "JPG (*.jpg)", 16, "ScreenCapture", "Captured Image")
    FileCopy(@ScriptDir & "\temp.jpg", $savePath & ".jpg", 1)
    cGUI_Close()
EndFunc   ;==>_Save

Func _Cancel()

EndFunc   ;==>_Cancel

Func mGUI_Close()
    DllClose($dc)
    FileDelete(@ScriptDir & "\temp.jpg")
    Exit
EndFunc   ;==>mGUI_Close

Func cGUI_Close()
    $editValue = False
    GUICtrlSetData($hEdit_Button, "Edit")
    GUICtrlSetState($hSave_Button, $GUI_DISABLE)
    GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
    FileDelete(@ScriptDir & "\temp.jpg")
    GUIDelete("Captured Image")
EndFunc   ;==>cGUI_Close
btw, I've also noticed this script does not work with multiple monitors, why so? Edited by Wombat

Just look at us.
Everything is backwards; everything is upside down. Doctors destroy health. Lawyers destroy justice. Universities destroy knowledge. Governments destroy freedom. The major media destroy information and religions destroy spirituality. ~ Michael Ellner


The internet is our one and only hope at a truly free world, do not let them take it from us...

Link to comment
Share on other sites

Alright so I have this script that I pulled from the depths of the forum, Melba23 was the author of the original code. I changed it to meet my requirements (thank you Melba23)

I now wish to add the functionality of being able to draw on the image, as well as being able to save the edited file. Where do I start, I've scavenged, dug around and can't find any examples that help.

I'm looking for the simplest way to do this, I know I can use GDI, but I would like to avoid that if possible.

Anywho, here is the code:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
#include <StaticConstants.au3>
#include <File.au3>
#include <Array.au3>

Opt("GUIOnEventMode", 1)

Global Const $SYSTEMROOT = EnvGet('systemdrive')
Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path, $dc
Global $editValue = False



; Create GUI
$hMain_GUI = GUICreate("Select Rectangle", 400, 50)
GUISetOnEvent($GUI_EVENT_CLOSE, "mGUI_Close", "Select Rectangle")

$hRect_Button = GUICtrlCreateButton("Capture", 10, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Capture")
$hCancel_Button = GUICtrlCreateButton("Cancel", 310, 10, 80, 30)
GUICtrlSetOnEvent(-1, "mGUI_Close")
$hEdit_Button = GUICtrlCreateButton("Edit", 110, 10, 80, 30)
GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
GUICtrlSetOnEvent(-1, "_Edit")
$hSave_Button = GUICtrlCreateButton("Save", 210, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Save")
GUICtrlSetState($hSave_Button, $GUI_DISABLE)

GUISetState()

While 1

    Sleep(10)
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, "", 75)
    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   ;==>_GUICreateInvRect

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

Func _Capture()
    If WinExists("Captured Image", "") = 1 Then GUIDelete("Captured Image")
    FileDelete(@ScriptDir & "\temp.jpg")
    GUISetState(@SW_HIDE, $hMain_GUI)
    Mark_Rect()
    ; Capture selected area
    $sBMP_Path = @ScriptDir & "\temp.jpg"
    _ScreenCapture_Capture($sBMP_Path, $iX1, $iY1, $iX2, $iY2, False)
    GUISetState(@SW_SHOW, $hMain_GUI)
    WinMove("Select Rectangle", "", Default + 75, Default + 100)
    GUICtrlSetState($hSave_Button, $GUI_ENABLE)
    GUICtrlSetState($hEdit_Button, $GUI_ENABLE)
    ; Display image
    $hBitmap_GUI = GUICreate("Captured Image", $iX2 - $iX1 + 50, $iY2 - $iY1 + 50, Default, Default)
    GUISetBkColor(0x525252, "Captured Image")
    GUISetOnEvent($GUI_EVENT_CLOSE, "cGUI_Close", "Captured Image")
    $hPic = GUICtrlCreatePic(@ScriptDir & "\temp.jpg", 25, 25, $iX2 - $iX1 + 1, $iY2 - $iY1 + 1)
    GUISetState()
EndFunc   ;==>_Capture

Func _Edit()

EndFunc   ;==>_Edit

Func _Save()
    Local $scPath = @DocumentsCommonDir & "\MyScreenCaptures\"
    If Not FileExists($scPath) Then DirCreate($scPath)
    Local $savePath = FileSaveDialog("Save your screen capture", $scPath, "JPG (*.jpg)", 16, "ScreenCapture", "Captured Image")
    FileCopy(@ScriptDir & "\temp.jpg", $savePath & ".jpg", 1)
    cGUI_Close()
EndFunc   ;==>_Save

Func _Cancel()

EndFunc   ;==>_Cancel

Func mGUI_Close()
    DllClose($dc)
    FileDelete(@ScriptDir & "\temp.jpg")
    Exit
EndFunc   ;==>mGUI_Close

Func cGUI_Close()
    $editValue = False
    GUICtrlSetState($hSave_Button, $GUI_DISABLE)
    GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
    FileDelete(@ScriptDir & "\temp.jpg")
    GUIDelete("Captured Image")
EndFunc   ;==>cGUI_Close

btw, I've also noticed this script does not work with multiple monitors, why so?

 

I think without using GDI/GDI+ it is not possible to modify the taken screenshot. 

I cannot remember whether this version already supports multi monitors but you can give a try -> 

Otherwise AutoIt Windows Screenshooter supports multiple monitors. ;)

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

I think without using GDI/GDI+ it is not possible to modify the taken screenshot. 

 

I cannot remember whether this version already supports multi monitors but you can give a try -> 

 

Otherwise AutoIt Windows Screenshooter supports multiple monitors. ;)

 

Br,

UEZ

Thank you UEZ, I'll look into that link... maybe GDI is the direction to take

Just look at us.
Everything is backwards; everything is upside down. Doctors destroy health. Lawyers destroy justice. Universities destroy knowledge. Governments destroy freedom. The major media destroy information and religions destroy spirituality. ~ Michael Ellner


The internet is our one and only hope at a truly free world, do not let them take it from us...

Link to comment
Share on other sites

I assume that this version is not supporting multiple monitors. I'm on holidays now for 3 weeks and I cannot test multiple monitors features yet but GDI+ should be the direction to drive.

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Alright, so I solved the multiple screen issue by editing the code here:

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

and here:

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

by multiplying the @DesktopWidth*2

 

I'm still looking for a way to draw directly on the captured image.

Just look at us.
Everything is backwards; everything is upside down. Doctors destroy health. Lawyers destroy justice. Universities destroy knowledge. Governments destroy freedom. The major media destroy information and religions destroy spirituality. ~ Michael Ellner


The internet is our one and only hope at a truly free world, do not let them take it from us...

Link to comment
Share on other sites

That's not a good approach - use this instead:

$hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]")
$aFullScreen = WinGetPos($hFullScreen)
$aFullScreen array has everything you need for multiple monitors support (not tested for 3+ monitors).

 

Unfortunatelly you cannot draw directly to a bitmap. You have to create a graphic context to the GDI+ bitmap to draw something onto the bitmap.

First you have to convert the GDI bitmap to GDI+ bitmap, then create the graphic context. Afterwards to can draw to the bitmap wrapped by the graphic context.

 

 

Try this:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
#include <StaticConstants.au3>
#include <File.au3>
#include <Array.au3>

Opt("GUIOnEventMode", 1)

Global Const $SYSTEMROOT = EnvGet('systemdrive'), $STM_SETIMAGE = 0x0172, $IMAGE_BITMAP = 0
Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path, $dc, $hGDIPlusBitmap, $hGDIBitmap
Global $editValue = False


_GDIPlus_Startup()
; Create GUI
$hMain_GUI = GUICreate("Select Rectangle", 400, 50)
GUISetOnEvent($GUI_EVENT_CLOSE, "mGUI_Close", "Select Rectangle")

$hRect_Button = GUICtrlCreateButton("Capture", 10, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Capture")
$hCancel_Button = GUICtrlCreateButton("Cancel", 310, 10, 80, 30)
GUICtrlSetOnEvent(-1, "mGUI_Close")
$hEdit_Button = GUICtrlCreateButton("Edit", 110, 10, 80, 30)
GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
GUICtrlSetOnEvent(-1, "_Edit")
$hSave_Button = GUICtrlCreateButton("Save", 210, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Save")
GUICtrlSetState($hSave_Button, $GUI_DISABLE)

GUISetState()

While 1

    Sleep(10)
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, "", 75)
    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   ;==>_GUICreateInvRect

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

Func _Capture()
    If WinExists("Captured Image", "") = 1 Then GUIDelete("Captured Image")
;~     FileDelete(@ScriptDir & "\temp.jpg")
    GUISetState(@SW_HIDE, $hMain_GUI)
    Mark_Rect()
    ; Capture selected area
;~     $sBMP_Path = @ScriptDir & "\temp.jpg"
    If $hGDIBitmap Then _WinAPI_DeleteObject($hGDIBitmap)
    $hGDIBitmap = _ScreenCapture_Capture("", $iX1, $iY1, $iX2, $iY2, False)
    If $hGDIPlusBitmap Then _GDIPlus_BitmapDispose($hGDIPlusBitmap) ;dispose ressource to avoid memory leak
    $hGDIPlusBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hGDIBitmap)
    _WinAPI_DeleteObject($hGDIBitmap) ;the GDI bitmap is not needed anymore
    Local $hGfxContext = _GDIPlus_ImageGetGraphicsContext($hGDIPlusBitmap)
    _GDIPlus_GraphicsDrawString($hGfxContext, "AutoIt rulez!", 0, 0, "Arial", 20)
    _GDIPlus_GraphicsDispose($hGfxContext)
    $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hGDIPlusBitmap) ;create GDI bitmap to send it to the pic control later
    GUISetState(@SW_SHOW, $hMain_GUI)
    WinMove("Select Rectangle", "", Default + 75, Default + 100)
    GUICtrlSetState($hSave_Button, $GUI_ENABLE)
    GUICtrlSetState($hEdit_Button, $GUI_ENABLE)
    ; Display image
    $hBitmap_GUI = GUICreate("Captured Image", $iX2 - $iX1 + 50, $iY2 - $iY1 + 50, Default, Default)
    GUISetBkColor(0x525252, "Captured Image")
    GUISetOnEvent($GUI_EVENT_CLOSE, "cGUI_Close", "Captured Image")
    $hPic = GUICtrlCreatePic("", 25, 25, $iX2 - $iX1 + 1, $iY2 - $iY1 + 1)
    _WinAPI_DeleteObject(GUICtrlSendMsg($hPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap))
    GUISetState()
EndFunc   ;==>_Capture

Func _Edit()
    If $editValue=False Then
        $editValue=True
        GUICtrlSetData($hEdit_Button, "Stop")
    ElseIf $editValue=True Then
        $editValue=False
        GUICtrlSetData($hEdit_Button, "Edit")
    EndIf
EndFunc   ;==>_Edit

Func _Save()
    Local $scPath = @DocumentsCommonDir & "\MyScreenCaptures\"
    If Not FileExists($scPath) Then DirCreate($scPath)
    Local $savePath = FileSaveDialog("Save your screen capture", $scPath, "JPG (*.jpg)", 16, "ScreenCapture", "Captured Image")
;~     FileCopy(@ScriptDir & "\temp.jpg", $savePath & ".jpg", 1)
    _GDIPlus_ImageSaveToFile($hGDIPlusBitmap, $savePath & ".jpg")
    cGUI_Close()
EndFunc   ;==>_Save

Func _Cancel()

EndFunc   ;==>_Cancel

Func mGUI_Close()
    DllClose($dc)
;~     FileDelete(@ScriptDir & "\temp.jpg")
    If $hGDIPlusBitmap Then _GDIPlus_BitmapDispose($hGDIPlusBitmap)
    If $hGDIBitmap Then _WinAPI_DeleteObject($hGDIBitmap)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>mGUI_Close

Func cGUI_Close()
    $editValue = False
    GUICtrlSetData($hEdit_Button, "Edit")
    GUICtrlSetState($hSave_Button, $GUI_DISABLE)
    GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
;~     FileDelete(@ScriptDir & "\temp.jpg")
    GUIDelete("Captured Image")
EndFunc   ;==>cGUI_Close
Edit: forgot to dispose the GDI bitmap to avoid memory leak.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

What did i do wrong here? I'm honestly lost... and tired sorry :/

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
#include <StaticConstants.au3>
#include <File.au3>
#include <Array.au3>

Opt("GUIOnEventMode", 1)

Global Const $SYSTEMROOT = EnvGet('systemdrive'), $STM_SETIMAGE = 0x0172, $IMAGE_BITMAP = 0
Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path, $dc, $hGDIPlusBitmap, $hGDIBitmap, $hPic

Global $editValue = False


_GDIPlus_Startup()
; Create GUI
$hMain_GUI = GUICreate("Select Rectangle", 400, 50)
GUISetOnEvent($GUI_EVENT_CLOSE, "mGUI_Close", "Select Rectangle")

$hRect_Button = GUICtrlCreateButton("Capture", 10, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Capture")
$hCancel_Button = GUICtrlCreateButton("Cancel", 310, 10, 80, 30)
GUICtrlSetOnEvent(-1, "mGUI_Close")
$hEdit_Button = GUICtrlCreateButton("Edit", 110, 10, 80, 30)
GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
GUICtrlSetOnEvent(-1, "_Edit")
$hSave_Button = GUICtrlCreateButton("Save", 210, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Save")
GUICtrlSetState($hSave_Button, $GUI_DISABLE)

GUISetState()

While 1

    Sleep(10)
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, "", 75)
    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   ;==>_GUICreateInvRect

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

Func _Capture()
    If WinExists("Captured Image", "") = 1 Then GUIDelete("Captured Image")
;~     FileDelete(@ScriptDir & "\temp.jpg")
    GUISetState(@SW_HIDE, $hMain_GUI)
    Mark_Rect()
    ; Capture selected area
;~     $sBMP_Path = @ScriptDir & "\temp.jpg"
    If $hGDIBitmap Then _WinAPI_DeleteObject($hGDIBitmap)
    $hGDIBitmap = _ScreenCapture_Capture("", $iX1, $iY1, $iX2, $iY2, False)
    If $hGDIPlusBitmap Then _GDIPlus_BitmapDispose($hGDIPlusBitmap) ;dispose ressource to avoid memory leak
    $hGDIPlusBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hGDIBitmap)
    _WinAPI_DeleteObject($hGDIBitmap) ;the GDI bitmap is not needed anymore
    Local $hGfxContext = _GDIPlus_ImageGetGraphicsContext($hGDIPlusBitmap)
    _GDIPlus_GraphicsDispose($hGfxContext)
    $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hGDIPlusBitmap) ;create GDI bitmap to send it to the pic control later
    GUISetState(@SW_SHOW, $hMain_GUI)
    WinMove("Select Rectangle", "", Default + 75, Default + 100)
    GUICtrlSetState($hSave_Button, $GUI_ENABLE)
    GUICtrlSetState($hEdit_Button, $GUI_ENABLE)
    ; Display image
    $hBitmap_GUI = GUICreate("Captured Image", $iX2 - $iX1 + 50, $iY2 - $iY1 + 50, Default, Default)
    GUISetBkColor(0x525252, "Captured Image")
    GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "_Paint", "Captured Image")
    GUISetOnEvent($GUI_EVENT_CLOSE, "cGUI_Close", "Captured Image")
    $hPic = GUICtrlCreatePic("", 25, 25, $iX2 - $iX1 + 1, $iY2 - $iY1 + 1)
    _WinAPI_DeleteObject(GUICtrlSendMsg($hPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap))
    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    GUISetState()
EndFunc   ;==>_Capture

Func _Paint()
    If $editValue=True Then
            Do

        $cPos = GUIGetCursorInfo()
        _GDIPlus_GraphicsFillRect($hPic, $cPos[0] - 1, $cPos[1] - 1, 7, 5)

        ;don't wait for the processing of the GUI
        _Winapi_PostMessage($hGDIPlusBitmap, $WM_PAINT, 0, 0)

    Until Not $cPos[2]
    Else
        Sleep(10)
    EndIf
EndFunc

Func _Edit()
    If $editValue=False Then
        $editValue=True
        GUICtrlSetData($hEdit_Button, "Stop")
    ElseIf $editValue=True Then
        $editValue=False
        GUICtrlSetData($hEdit_Button, "Edit")
    EndIf
EndFunc   ;==>_Edit

Func _Save()
    Local $scPath = @DocumentsCommonDir & "\MyScreenCaptures\"
    If Not FileExists($scPath) Then DirCreate($scPath)
    Local $savePath = FileSaveDialog("Save your screen capture", $scPath, "JPG (*.jpg)", 16, "ScreenCapture", "Captured Image")
;~     FileCopy(@ScriptDir & "\temp.jpg", $savePath & ".jpg", 1)
    _GDIPlus_ImageSaveToFile($hGDIPlusBitmap, $savePath & ".jpg")
    cGUI_Close()
EndFunc   ;==>_Save

Func _Cancel()

EndFunc   ;==>_Cancel

Func mGUI_Close()
    DllClose($dc)
;~     FileDelete(@ScriptDir & "\temp.jpg")
    If $hGDIPlusBitmap Then _GDIPlus_BitmapDispose($hGDIPlusBitmap)
    If $hGDIBitmap Then _WinAPI_DeleteObject($hGDIBitmap)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>mGUI_Close

Func cGUI_Close()
    $editValue = False
    GUICtrlSetData($hEdit_Button, "Edit")
    GUICtrlSetState($hSave_Button, $GUI_DISABLE)
    GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
;~     FileDelete(@ScriptDir & "\temp.jpg")
    GUIDelete("Captured Image")
EndFunc   ;==>cGUI_Close

Func WM_PAINT($hWnd, $iMsg, $wParam, $lParam)

    ;paint the buffer image on the GUI.
    _GDIPlus_GraphicsDrawImage($hGDIPlusBitmap, $hPic, 0, 0)

EndFunc   ;==>WM_PAINT

Just look at us.
Everything is backwards; everything is upside down. Doctors destroy health. Lawyers destroy justice. Universities destroy knowledge. Governments destroy freedom. The major media destroy information and religions destroy spirituality. ~ Michael Ellner


The internet is our one and only hope at a truly free world, do not let them take it from us...

Link to comment
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
 Share

  • Recently Browsing   0 members

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