Jump to content

Having selection on virtual screen


marcgforce
 Share

Recommended Posts

Hello guys,

I'm asking for help, i have a script that captures a region of the screen defined by drawing a rectangle with mouse on it; it works perfectly when there's only one screen attached to the computer but when a second screen is connected, the rectangle  is not shown on the virtualized screen...

someone could fix this script, i'm turning around without founding the solution...

 

#include <Date.au3>
#include<array.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <ScreenCapture.au3>
#Include <Misc.au3>
#include <EditConstants.au3>
#include <Clipboard.au3>

Global $pos, $sfilename_complete
Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path
Global Const $IMAGE = $sfilename_complete ; Location of the image file to print
Global $s_ProgramTitle01 = "Select Rectangle"
Global $visionner = False
HotKeySet("{PRINTSCREEN}","_capture")

Opt("TrayMenuMode",1)
Local $trayMenuLancer = TrayCreateItem("Voir la capture")
TrayItemSetState($trayMenuLancer,4)
Local $trayMenu = TrayCreateItem ("Quitter")

While 1
    $nsystray = TrayGetMsg()
    Select
        case $nsystray = $trayMenuLancer
            If $visionner = False Then
                TrayItemSetState($trayMenuLancer,1)
                $visionner = True
            Else
                $visionner = False
                TrayItemSetState($trayMenuLancer,4)
            EndIf

        case $nsystray = $trayMenu
            Exit
    EndSelect
    sleep(100)
WEnd

Func _capture()
    local $aRet = Mark_Rect()
    If IsArray($aRet) then
        Local $hGUI, $hBMP, $hBitmap, $hGraphic, $hImage, $iX, $iY, $hClone
        $input_name = Inputbox("Capture","Entrer le nom de la capture écran", "capture-" & StringReplace(_nowtime(),":",""))
        if @error == 1 then Return
        while  _CheckForbidden($input_name) <> 0
            msgbox (64,"Erreur", "Erreur, le nom comporte des caractères interdits :"& @CRLF & '["/\\*?<>|:]')
            $input_name = Inputbox("Capture","Entrer le nom de la capture écran", "capture-" & StringReplace(_nowtime(),":",""))
            if @error == 1 then Return
        wend
        local $sfilename = $input_name
        $sfilename_jpg_complete = @MyDocumentsDir & "\" & $sfilename & ".jpg"
        $sfilename_bmp_complete = @MyDocumentsDir & "\" & $sfilename & ".bmp"
        sleep (500)
           ; Capture un bitmap 32 bits
        $hBMP = _ScreenCapture_Capture(@MyDocumentsDir & "\" & $sfilename & ".bmp", $iX1, $iY1, $iX2, $iY2, False)
        $hJPG = _ScreenCapture_Capture(@MyDocumentsDir & "\" & $sfilename & ".jpg", $iX1, $iY1, $iX2, $iY2, False)
        $hClipboard_Bitmap = _WinAPI_LoadImage("",$sfilename_bmp_complete, $IMAGE_BITMAP, $iX2-$iX1,$iy2-$iy1,$LR_LOADFROMFILE)
        _ClipBoard_Open(0)
        _ClipBoard_Empty()
        _ClipBoard_SetDataEx($hClipboard_Bitmap,$CF_BITMAP)
        _ClipBoard_Close()
        FileDelete($sfilename_bmp_complete)
        if not $hClipboard_Bitmap then
            Msgbox(64,"Erreur", "Image non capturée")
        Else
            msgbox(0,"Capture","Le fichier à été copié dans " & $sfilename_jpg_complete & " et placé dans le Presse papiers",1)
            if $visionner Then ShellExecute($sfilename_jpg_complete)
        EndIf
        ;ShellExecute($sfilename_complete)
    Else
        Return $aRet
    EndIf
 EndFunc   ;==> _capture


Func Mark_Rect()
    Local $deskSurface = _GetVirtualScreen()
    Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
    Local $UserDLL = DllOpen("user32.dll")
    Local $aRet[4]
    ; Create transparent GUI with Cross cursor
    $hCross_GUI = GUICreate("Test", $deskSurface[1] - $deskSurface[0] , $deskSurface[3] - 20, $deskSurface[0], $deskSurface[2], $WS_POPUP, $WS_EX_TOPMOST)
    WinSetTrans($hCross_GUI, "", 8)
    GUISetState(@SW_SHOW, $hCross_GUI)
    GUISetCursor(3, 1, $hCross_GUI)



    ; Wait until mouse button pressed
    While Not _IsPressed("01", $UserDLL)
        Sleep(10)
        if _IsPressed("1B", $UserDLL) then
            ;GUIDelete( $hRectangle_GUI)
            GUIDelete($hCross_GUI)
            DllClose($UserDLL)
            $aRet = "ESC"
            return $aRet
        EndIf
    WEnd

    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]
    ConsoleWrite($iX1 & @tab & $iy1 & @CRLF)
    Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST) ; initial value
    ;Global $hRectangle_GUI = GUICreate("", $deskSurface[1] - $deskSurface[0] , $deskSurface[3], $deskSurface[0],  $deskSurface[2], $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST); modification that doesn't work like i want.
    GUISetBkColor(0x000000)
    ;guisetstate(@SW_SHOW,$hRectangle_GUI)
    ; $WS_EX_TOOLWINDOW +
    ; 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)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($iX1, $iY1, $iX1 + 1, $aMouse_Pos[1]) ; Left of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($iX1 + 1, $iY1 + 1, $aMouse_Pos[0], $iY1) ; Top of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $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)
        _WinAPI_DeleteObject($hMask)
        ; 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)
    $aRet[0] = $iX1
    $aRet[1] = $iY1
    $aRet[2] = $iX2
    $aRet[3] = $iY2

    if ($iX2-$iX1)+($iY2-$iY1) < 150 Then
        msgbox(0,"Erreur","Capture trop petite : "& ($iX2-$iX1)+($iY2-$iY1) & " Pixel(s), non enregistrée",2)
        $aRet = ""
        $aRet = "ESC"
    EndIf

    return $aRet


EndFunc   ;==>Mark_Rect

Func _GetVirtualScreen()
;~ 'Virtual Desktop sizes
    Local $SM_XVIRTUALSCREEN = 76   ; 'Virtual Left
    Local $SM_YVIRTUALSCREEN = 77   ; 'Virtual Top
    Local $SM_CXVIRTUALSCREEN = 78  ; 'Virtual Width
    Local $SM_CYVIRTUALSCREEN = 79  ; 'Virtual Height

    Dim $xyScreen[4]
    Dim $VirtualScreen[4] = [$SM_XVIRTUALSCREEN, $SM_CXVIRTUALSCREEN, $SM_YVIRTUALSCREEN, $SM_CYVIRTUALSCREEN]

    For $x = 0 To 3
        $xTemp = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $VirtualScreen[$x])
        If $x = 1 Then
;~ Note: $SM_CXVIRTUALSCREEN + $SM_XVIRTUALSCREEN = $RightSideScreen
            $xyScreen[$x] = ($xTemp[0] + $xyScreen[$x - 1]) - 1
        Else
            $xyScreen[$x] = $xTemp[0]
            If $x = 3 Then $xyScreen[$x] -= 1
        EndIf
    Next
    Return ($xyScreen)
EndFunc   ;==>_GetVirtualScreen

Func _CheckForbidden($string)
  Local $pattern_forbid = '["/\\*?<>|:]'
  Return  StringRegExp($string, $pattern_forbid)
EndFunc

Thanks...

Link to comment
Share on other sites

Hey

use

While 1
    If _IsPressed ( "2C" ) Then _capture()
    $nsystray = TrayGetMsg()
    Select
        case $nsystray = $trayMenuLancer
            If $visionner = False Then
                TrayItemSetState($trayMenuLancer,1)
                $visionner = True
            Else
                $visionner = False
                TrayItemSetState($trayMenuLancer,4)
            EndIf

        case $nsystray = $trayMenu
            Exit
    EndSelect
    sleep(100)
WEnd

instead of

HotKeySet("{PRINTSCREEN}","_capture")

because if you run the script twice, the hotkey is already used. Hotkeyset is a bit weird :P

Helpfile:

Quote

If two AutoIt scripts set the same hotkeys, you should avoid running those scripts simultaneously as the second script cannot capture the hotkey unless the first script terminates or unregisters the key prior to the second script setting the hotkey. If the scripts use GUIs, then consider using GUISetAccelerators as these keys are only active when the parent GUI is active.

 

so it also should work when you close the script on the other desktops.

best Regards

Edited by Aelc

why do i get garbage when i buy garbage bags? <_<

Link to comment
Share on other sites

Thanks for reply but my problem is not on the hotsetkey function, just when you use two screens on your desktop and want to capture something by drawing a restangle with the mouse, the rectangle is shown on the main screen (when you capture on it) and not on the second (if you capture on it)...

 

Thanks

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