ken82m Posted May 20, 2010 Share Posted May 20, 2010 (edited) I got a start with http://www.autoitscript.com/forum/index.php?showtopic=111185&st=0But I've gone a bit outside the scope so I decided to open a new thread.So you know where I'm going with this, I'm trying to:1) Create a GUI that can load an image from the clipboard.2) Allow the user to select of area of that graphic to crop.3) Save the cropped image as a PNG or JPGQuestion 1I modified the script above and successfully created a window that I can use to make my selection.But the exit button and "X" won't respond so I can't close the window.Along with any other control I'd create.Question 2And I can't restrict the selection to the window i created.I tried this in the func, but it caused the window to flash;ElseIf Not WinActive($hCross_GUI) Then ; Window flashes if this statement is active ; GUIDelete($hRectangle_GUI) ; DllClose($UserDLL) ; Return 0 EndIfQuestion 3Does anyone know how I can load an image in the clipboard into a GUI?Image is generated by printscreen button.Thanks,Kennyexpandcollapse popup#cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.6.1 Author: Kenneth P. Morrissey Script Function: Create selection rectangle within an AutoIT window. #ce ---------------------------------------------------------------------------- ; Credit: Malkey for the basic GDI code #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #Include <Misc.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> Global $iTolerance = 30, $iX1, $iY1, $iX2, $iY2, $fType = "" HotKeySet("{F3}", "ExitNow") ; Create transparent GUI with Cross cursor $hCross_GUI = GUICreate("Test", 400, 400, -1, -1, "", $WS_EX_TOPMOST) GUISetState(@SW_SHOW, $hCross_GUI) GUISetCursor(3, 1, $hCross_GUI) $button = GUICtrlCreateButton("exit",10,10, 100) ;Loop waiting for Mark_Rect() to confirm coords withing GUI window. While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Exit Case $button Exit EndSwitch $Return = Mark_Rect() If $Return Then MsgBox(262144, "", $iX1 & @CR & $iY1 & @CR & $iX2 & @CR & $iY2) Sleep(10) WEnd Func ExitNow() Exit EndFunc 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) 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) $WinPos = WinGetPos($hCross_GUI) $WinPos[2] = $WinPos[0] + $WinPos[2] $WinPos[1] = $WinPos[1] + 70 $WinPos[3] = $WinPos[1] + $WinPos[3] $aMouse_Pos = MouseGetPos() If $aMouse_Pos[0] < $WinPos[0] OR $aMouse_Pos[1] > $WinPos[3] Then GUIDelete($hRectangle_GUI) DllClose($UserDLL) Return 0 ElseIf $aMouse_Pos[1] < $WinPos[1] OR $aMouse_Pos[1] > $WinPos[3] Then GUIDelete($hRectangle_GUI) DllClose($UserDLL) Return 0 ;ElseIf Not WinActive($hCross_GUI) Then ; Window flashes if this statement is active ; GUIDelete($hRectangle_GUI) ; DllClose($UserDLL) ; Return 0 EndIf $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) DllClose($UserDLL) If $iX1 = $iX2 OR $iY1 = $iY2 Then Return 0 Return 1 EndFunc ;==>Mark_Rect Edited May 20, 2010 by ken82m "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains." Link to comment Share on other sites More sharing options...
ken82m Posted May 20, 2010 Author Share Posted May 20, 2010 oh and the reason I'm doing this is I'm running some stupid new program. And it screws with every screen shot app out there including AU3's functions. The only thing that gives me a screenshot right now is the actual "PRINTSCREEN" button on my keyboard. I'm trying to come up with something like one of my screen shot apps instead of dealing with paint or photoshop or whatever. "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains." Link to comment Share on other sites More sharing options...
Malkey Posted May 20, 2010 Share Posted May 20, 2010 (edited) This works on my XP. expandcollapse popup#include <GDIPlus.au3> #include <WinAPI.au3> #include <GuiConstants.au3> #include <WindowsConstants.au3> #include <ClipBoard.au3> #include <Misc.au3> ; http://www.autoitscript.com/forum/index.php?showtopic=114679&view=findpost&p=801509 Opt("MouseCoordMode", 2) ;1=absolute, 0=relative, 2=client HotKeySet("{F3}", "_SaveRect") Global $hGui, $hGraphicGUI, $hBMPBuff, $aSP, $aMP, $GuiSizeX = 800, $GuiSizeY = 600 Local $hBMP, $hImage, $hGraphic Local $x = 0, $y = 0, $w = @DesktopWidth, $h = @DesktopHeight ; Prnt Scrn size Send("{PRINTSCREEN}") ; Screen ;Send("!{PRINTSCREEN}") ; window $hGui = GUICreate("Press[F3] to save red rectangle area.", $GuiSizeX, $GuiSizeY) GUISetState() ; Open the clipboard If Not _ClipBoard_Open(0) Then _WinAPI_ShowError("_ClipBoard_Open failed") $hBMP = _ClipBoard_GetDataEx($CF_BITMAP) _GDIPlus_Startup() $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui) $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff) ;Graphics here ;_GDIPlus_GraphicsClear($hGraphic, 0xFFE8FFE8) $hPen = _GDIPlus_PenCreate(0xFFFF0000, 1) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hImage, $x, $y, $w, $h, 0, 0, $GuiSizeX, $GuiSizeY) ;End of graphics GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE _GDIPlus_PenDispose($hPen) _GDIPlus_ImageDispose($hImage) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hGraphicGUI) _GDIPlus_BitmapDispose($hBMPBuff) _GDIPlus_Shutdown() _ClipBoard_Close() Exit EndSwitch If _IsPressed("01") Then $aSP = MouseGetPos() ;mouse Start Position Do $aMP = MouseGetPos() _GDIPlus_GraphicsClear($hGraphic, 0xFFE8FFE8) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hImage, $x, $y, $w, $h, 0, 0, $GuiSizeX, $GuiSizeY) _GDIPlus_GraphicsDrawRect($hGraphic, $aSP[0], $aSP[1], $aMP[0] - $aSP[0], $aMP[1] - $aSP[1], $hPen) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) Sleep(10) Until Not _IsPressed("01") EndIf WEnd Func _SaveRect() Local $ScaleX = @DesktopWidth / $GuiSizeX, $ScaleY = @DesktopHeight / $GuiSizeY Local $hClone = _GDIPlus_BitmapCloneArea($hImage, $aSP[0] * $ScaleX, $aSP[1] * $ScaleY, ($aMP[0] - $aSP[0]) * $ScaleX, ($aMP[1] - $aSP[1]) * $ScaleY, $GDIP_PXF32ARGB) _GDIPlus_ImageSaveToFile($hClone, @DesktopDir & "\Imagetst.tif") ;$sNewName) _GDIPlus_BitmapDispose($hClone) ShellExecute(@DesktopDir & "\Imagetst.tif") EndFunc ;==>_SaveRect ;Func to redraw on PAINT MSG Func MY_PAINT($hWnd, $msg, $wParam, $lParam) _WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW)) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) Return $GUI_RUNDEFMSG EndFunc ;==>MY_PAINT Edit: Added _GDIPlus_PenDispose($hPen). :20 May 2010 - 01:29 PM Edit: Deleted _WinAPI_DeleteObject($hBMP) altogether. Clipboard controls the handle returned from _ClipBoard_GetDataEx(). Changed all remaining _WinAPI_DeleteObject() to _GDIPlus_BitmapDispose (). Edited June 10, 2010 by Malkey Link to comment Share on other sites More sharing options...
ken82m Posted May 21, 2010 Author Share Posted May 21, 2010 That's working greate thanks! I made a few changes so it would keep running in the background letting me take more screenshots. expandcollapse popup#include <ClipBoard.au3> #include <_FileSaveDialog.au3> #include <GDIPlus.au3> #include <GuiConstants.au3> #include <Misc.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> ; [url="http://www.autoitscript.com/forum/index.php?showtopic=114679&view=findpost&p=801509"]http://www.autoitscript.com/forum/index.php?showtopic=114679&view=findpost&p=801509[/url] Opt("MouseCoordMode", 2) ;1=absolute, 0=relative, 2=client HotKeySet("{F3}", "_SaveRect") HotKeySet("{F9}", "_Exit") Global $hGui, $hGraphicGUI, $hBMPBuff, $aSP, $aMP, $GuiSizeX = @DesktopWidth-50, $GuiSizeY = @DesktopHeight-50, $hImageHeight = 0, $hImageHeight = 0 Local $hBMP, $hImage, $hGraphic, $w, $h Local $x = 0, $y = 0, $w = @DesktopWidth, $h = @DesktopHeight ; Prnt Scrn size ;Kenny Test============================ HotKeySet("{PRINTSCREEN}", "_PrtScr") HotKeySet("!{PRINTSCREEN}", "_AltPrtScr") While 1 Sleep(100) WEnd Func _PrtScr() HotKeySet("{PRINTSCREEN}") Send("{PRINTSCREEN}") HotKeySet("{PRINTSCREEN}", "_PrtScr") _EditShot() EndFunc ;==> _PrtScr Func _AltPrtScr() HotKeySet("!{PRINTSCREEN}") Send("!{PRINTSCREEN}") HotKeySet("!{PRINTSCREEN}", "_AltPrtScr") _EditShot() EndFunc ;==> _AltPrtScr Func _Exit() Exit EndFunc ;==> _Exit ;Kenny Test============================== Func _EditShot() $hGui = GUICreate("Press[F3] to save red rectangle area.", $GuiSizeX, $GuiSizeY, -1, -1, $WS_MAXIMIZE) $filemenu = GUICtrlCreateMenu("&File") $SaveBtn = GUICtrlCreateMenuItem("Save Image", $filemenu) GUICtrlCreateMenuItem("", $filemenu, 2) ; create a separator line $CloseBtn = GUICtrlCreateMenuItem("Close Window", $filemenu) GUISetState() ; Open the clipboard If Not _ClipBoard_Open(0) Then _WinAPI_ShowError("_ClipBoard_Open failed") $hBMP = _ClipBoard_GetDataEx($CF_BITMAP) _GDIPlus_Startup() $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui) $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff) MsgBox(0,"",$hImageHeight & @Cr & $hImageWidth) ;Graphics here ;_GDIPlus_GraphicsClear($hGraphic, 0xFFE8FFE8) $hPen = _GDIPlus_PenCreate(0xFFFF0000, 1) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hImage, $x, $y, $w, $h, 0, 0, $GuiSizeX, $GuiSizeY) ;End of graphics GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE _GDIPlus_PenDispose($hPen) _GDIPlus_ImageDispose($hImage) _WinAPI_DeleteObject($hBMP) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hGraphicGUI) _WinAPI_DeleteObject($hBMPBuff) _GDIPlus_Shutdown() _ClipBoard_Close() GUIDelete($hGui) Return;Exit Case $CloseBtn _GDIPlus_PenDispose($hPen) _GDIPlus_ImageDispose($hImage) _WinAPI_DeleteObject($hBMP) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hGraphicGUI) _WinAPI_DeleteObject($hBMPBuff) _GDIPlus_Shutdown() _ClipBoard_Close() GUIDelete($hGui) Return;Exit Case $SaveBtn _SaveRect() EndSwitch If _IsPressed("01") Then $aSP = MouseGetPos() ;mouse Start Position Do $aMP = MouseGetPos() _GDIPlus_GraphicsClear($hGraphic, 0xFFE8FFE8) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hImage, $x, $y, $w, $h, 0, 0, $GuiSizeX, $GuiSizeY) _GDIPlus_GraphicsDrawRect($hGraphic, $aSP[0], $aSP[1], $aMP[0] - $aSP[0], $aMP[1] - $aSP[1], $hPen) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) Sleep(10) Until Not _IsPressed("01") EndIf WEnd EndFunc ;==>_EditShot Func _SaveRect() $sFilter = "PNG image (*.png)|*.png|JPEG image (*.jpg)|*.jpg|TIF image (*.tif)|*.tif|Bitmap image (*.bmp)|*.bmp|GIF image (*.gif)|*.gif" ;$SaveFile = _FileSaveDialog("Save As", @DesktopDir, $sFilter, 16+2, "", 1, $hGui) $SaveFile = FileSaveDialog("Save As", @DesktopDir, $sFilter, 16+2, "", $hGui) FileDelete($SaveFile) Local $ScaleX = @DesktopWidth / $GuiSizeX, $ScaleY = @DesktopHeight / $GuiSizeY Local $hClone = _GDIPlus_BitmapCloneArea($hImage, $aSP[0] * $ScaleX, $aSP[1] * $ScaleY, ($aMP[0] - $aSP[0]) * $ScaleX, ($aMP[1] - $aSP[1]) * $ScaleY, $GDIP_PXF32ARGB) ;_GDIPlus_ImageSaveToFile($hClone, $SaveFile) If Not _GDIPlus_ImageSaveToFile($hClone, $SaveFile) Then MsgBox(0, "Save File", "An error occured saving the image") Else ShellExecute($SaveFile) EndIf _WinAPI_DeleteObject($hClone) EndFunc ;==>_SaveRect ;Func to redraw on PAINT MSG Func MY_PAINT($hWnd, $msg, $wParam, $lParam) _WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW)) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) Return $GUI_RUNDEFMSG EndFunc ;==>MY_PAINT I only have one problem, if I hit the save button without selecting anything it blows up. I tried pulling the dimensions from the clipboard. Then I could just play with $aSP/$aMP so that the coords cover the entire image. $hImageHeight = _GDIPlus_ImageGetHeight($hImage) $hImageWidth = _GDIPlus_ImageGetWidth($hImage) But those functions always return a number larger that the actual image. For example, the windows Calculator: The image is actually 144x240 But $hImageWidth/Height return 230x324 And is it possible to refresh the screen? When I make a selection, to just show the cropped image? Thanks, Kenny "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains." Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now