Edit: nothing like posting to help you finally find an example that answers your question. Test number 4 works if I remove the " and % from around the variable.
I am trying to use ScreenCapture with Rhys gdi32 routine that lets me select a portion of the screen and I am getting nowhere real fast. Basically, I want the user to be able to select a portion of the screen and have it saved to a file, or the clipboard - neither of which works if I use variables for the
Here is Rhys' code, with a mod to save the xy's
Code:
;SetBatchLines, -1
OnExit, handle_exit
CoordMode, Mouse, Screen
line_c = 0x008000 ; line color
frame_c = 0x0000FF ; frame color
frame_t = 1 ; frame thickness
; added by Scott Mattes
rect_mx = 0
rect_my = 0
rect_mx_end = 0
rect_my_end = 0
; end of add by Scott Mattes
return
; end of autoexec
; When user clicks with Left-Mouse Button and drags, a frame is drawn on screen
+Lbutton::
;get starting position
MouseGetPos, MX, MY
; show transparent GUI covering the whole screen
Gui, 1:Color, Black
Gui, 1:+Lastfound +AlwaysOnTop
WinSet, TransColor, Black
Gui, 1:-Caption
Gui, Show, x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%
; retrieve the unique ID number (HWND/handle) of that window
WinGet, hw_frame, id
; The GetDC function retrieves a handle to
; a display device context (DC) for the client area
; of a specified window or for the entire screen.
; You can use the returned handle in subsequent GDI functions to draw in the DC.
hdc_frame := DllCall( "GetDC"
, "uint", hw_frame )
; create buffer to store old color data to remove drawn rectangles
; The CreateCompatibleDC function creates a memory device context (DC)
; compatible with the specified device.
hdc_buffer := DllCall( "gdi32.dll\CreateCompatibleDC"
, "uint", hdc_frame )
; The CreateCompatibleBitmap function creates a bitmap compatible
; with the device that is associated with the specified device context.
hbm_buffer := DllCall( "gdi32.dll\CreateCompatibleBitmap"
, "uint", hdc_frame
, "int", A_ScreenWidth
, "int", A_ScreenHeight )
; The SelectObject function selects an object into the specified
; device context (DC). The new object replaces the previous object of the same type.
DllCall( "gdi32.dll\SelectObject"
, "uint", hdc_buffer
, "uint", hbm_buffer )
; create a dummy rectangular region.
; The CreateRectRgn function creates a rectangular region.
h_region := DllCall( "gdi32.dll\CreateRectRgn"
, "int", 0
, "int", 0
, "int", 0
, "int", 0 )
; specify the color of the frame.
; The CreateSolidBrush function creates a logical
; brush that has the specified solid color.
h_brush := DllCall( "gdi32.dll\CreateSolidBrush"
, "uint", frame_c )
;check continously if the mouse is draged while LButton is down and redraw frame.
Loop
{
;redraw frame when LButton is still down
If GetKeyState("LButton", "P")
{
;get mouse position
MouseGetPos, MXend, MYend
;redraw only if mouse moved to a different position
If ( MXend <> MXend_old
AND MYend <> MYend_old)
{
;compute width and height of frame
w := abs(MX - MXend)
h := abs(MY - MYend)
;find upper left corner
X := Min( MX, MXend )
Y := Min( MY, MYend )
DrawFrame( X, Y, w, h, frame_t )
;memorize position
MXend_old = %MXend%
MYend_old = %MYend%
}
}
Else ;LButton is released
Break
Sleep, 50
}
GoSub, CleanUp
ToolTip, %MX% %MY%`n%MXend% %MYend%`n%w% %h%
; added by Scott Mattes
rect_mx = %mx%
rect_my = %my%
rect_mx_end = %mxend%
rect_my_end = %myend%
; end of add by Scott Mattes
Return
ESC::
handle_exit:
GoSub, CleanUp
ExitApp
Return
CleanUp:
DeleteObject( h_brush )
DeleteObject( h_region )
DeleteObject( hbm_buffer )
DeleteDC( hdc_frame )
DeleteDC( hdc_buffer )
Gui, 1:Destroy
Return
DrawFrame( p_x, p_y, p_w, p_h, p_t )
{
global hdc_frame, hdc_buffer, h_region, h_brush
static buffer_state, old_x, old_y, old_w, old_h
; Copies the source rectangle directly to the destination rectangle.
SRCCOPY = 0x00CC0020
;remove previously drawn rectangle (restore previoulsy buffered color data)
if ( buffer_state = "full")
; The BitBlt function performs a bit-block transfer of the color data
; corresponding to a rectangle of pixels from the specified
; source device context into a destination device context.
DllCall( "gdi32.dll\BitBlt"
, "uint", hdc_frame
, "int", old_x
, "int", old_y
, "int", old_w
, "int", old_h
, "uint", hdc_buffer
, "int", 0
, "int", 0
, "uint", SRCCOPY )
else
buffer_state = full
;remember new rectangle for next loop (to be removed)
old_x := p_x
old_y := p_y
old_w := p_w
old_h := p_h
; Store current color data of new ractangle in buffer
; The BitBlt function performs a bit-block transfer of the color data
; corresponding to a rectangle of pixels from the specified
; source device context into a destination device context.
DllCall( "gdi32.dll\BitBlt"
, "uint", hdc_buffer
, "int", 0
, "int", 0
, "int", p_w
, "int", p_h
, "uint", hdc_frame
, "int", p_x
, "int", p_y
, "uint", SRCCOPY )
; modify dummy rectangular region to desired reactangle
; The SetRectRgn function converts a region into a
; rectangular region with the specified coordinates.
DllCall( "gdi32.dll\SetRectRgn"
, "uint", h_region
, "int", p_x
, "int", p_y
, "int", p_x+p_w
, "int", p_y+p_h )
; draw region frame with thickness (width and hight are the same)
; The FrameRgn function draws a border around the
; specified region by using the specified brush.
DllCall( "gdi32.dll\FrameRgn"
, "uint", hdc_frame
, "uint", h_region
, "uint", h_brush
, "int", p_t
, "int", p_t )
/*
PS_DASH = PS_DASH
; The CreatePen function creates a logical pen that has the
; specified style, width, and color. The pen can subsequently
; be selected into a device context and used to draw lines and curves.
h_pen := DllCall( "gdi32.dll\CreatePen"
, "int", PS_DASH
, "int", p_t
, "uint", line_c)
; The SelectObject function selects an object into the specified
; device context (DC). The new object replaces the previous object of the same type.
h_penold := DllCall( "gdi32.dll\SelectObject"
, "uint", hdc_frame
, "uint", h_pen )
; The MoveToEx function updates the current position to
; the specified point and optionally returns the previous position.
DllCall( "gdi32.dll\MoveToEx"
, "uint", hdc_frame
, "int", p_x
, "int", p_y
, "uint", lppoint)
; The LineTo function draws a line from the current
; position up to, but not including, the specified point.
DllCall( "gdi32.dll\LineTo"
, "uint", hdc_frame
, "int", p_x+p_w
, "int", p_y+p_h)
DllCall( "gdi32.dll\MoveToEx"
, "uint", hdc_frame
, "int", p_x+p_w
, "int", p_y
, "uint", lppoint)
DllCall( "gdi32.dll\LineTo"
, "uint", hdc_frame
, "int", p_x
, "int", p_y+p_h)
; The SelectObject function selects an object into the specified
; device context (DC). The new object replaces the previous object of the same type.
DllCall( "gdi32.dll\SelectObject"
, "uint", hdc_frame
, "uint", h_penold )
DeleteObject( h_pen )
*/
}
DeleteDC( p_dc )
{
; The DeleteDC function deletes the specified device context (DC).
DllCall( "gdi32.dll\DeleteDC", "uint", p_dc )
}
DeleteObject( p_object )
{
; The DeleteObject function deletes a logical pen, brush,
; font, bitmap, region, or palette, freeing all system resources
; associated with the object. After the object is deleted,
; the specified handle is no longer valid.
DllCall( "gdi32.dll\DeleteObject", "uint", p_object )
}
Min( value1, value2 )
{
If ( value1 < value2 )
return value1
Else
return value2
}
here is my code to use it
Code:
clipboard = this is a test
filerecycle, c:\temp\screen.png
capturescreen( "686, 570, 832, 745", false, "c:\temp\screen.png" )
ifexist c:\temp\screen.png
msgbox, the file was made
else
msgbox, the file WAS NOT made
#include %A_ScriptDir%\ScreenCapture.ahk
#include %A_ScriptDir%\Rhys gdi32 drawrect.ahk
return
; use shift left mouse to get the rectangle values
#1:: ; test 1, use points captured by rhys' code
clip_save = %clipboardall%
msgbox, "%rect_mx%, %rect_my%, %rect_mx_end%, %rect_my_end%"
capturescreen( "rect_mx%, %rect_my%, %rect_mx_end%, %rect_my_end%", false, 0 )
msgbox, errorlevel-%errorlevel% running test 1
run, mspaint
WinWait, untitled - Paint,
IfWinNotActive, untitled - Paint, , WinActivate, untitled - Paint,
WinWaitActive, untitled - Paint,
Send, {SHIFTDOWN}{INS}{SHIFTUP}{ENTER}
; result, Paint reports "Error getting the Clipboard data"
clipboard = %clip_save%
return
#2:: ; test 1, use points captured by rhys' code
clip_save = %clipboardall%
msgbox, "%rect_mx%, %rect_my%, %rect_mx_end%, %rect_my_end%"
capturescreen( "rect_mx, rect_my, rect_mx_end, rect_my_end", false, 0 )
msgbox, errorlevel-%errorlevel% running test 2
run, mspaint
WinWait, untitled - Paint,
IfWinNotActive, untitled - Paint, , WinActivate, untitled - Paint,
WinWaitActive, untitled - Paint,
Send, {SHIFTDOWN}{INS}{SHIFTUP}{ENTER}
; result, Paint reports "Error getting the Clipboard data"
clipboard = %clip_save%
return
#3::
; test 2, use points captured by rhys' code
clip_save = %clipboardall%
msgbox, use points reported by rhys' code, but typed by me
capturescreen( "686, 570, 832, 745", false, 0 )
msgbox, errorlevel-%errorlevel% running test 3
run, mspaint
WinWait, untitled - Paint,
IfWinNotActive, untitled - Paint, , WinActivate, untitled - Paint,
WinWaitActive, untitled - Paint,
Send, {SHIFTDOWN}{INS}{SHIFTUP}{ENTER}
; result, Paint now contains part of the screen
clipboard = %clip_save%
return
#4:: ; test 3, use points captured by rhys' code, but put into a local variable first
clip_save = %clipboardall%
my_rect = "%rect_mx%, %rect_my%, %rect_mx_end%, %rect_my_end%"
msgbox, %my_rect%
capturescreen( "%my_rect%", false, 0 )
msgbox, errorlevel-%errorlevel% running test 4
run, mspaint
WinWait, untitled - Paint,
IfWinNotActive, untitled - Paint, , WinActivate, untitled - Paint,
WinWaitActive, untitled - Paint,
Send, {SHIFTDOWN}{INS}{SHIFTUP}{ENTER}
; result, Paint reports "Error getting the Clipboard data"
clipboard = %clip_save%
return
#5:: ; test 4, use points captured by rhys' code to save to a file
clip_save = %clipboardall%
msgbox, "%rect_mx%, %rect_my%, %rect_mx_end%, %rect_my_end%"
capturescreen( "%rect_mx%, %rect_my%, %rect_mx_end%, %rect_my_end%", false, "c:\temp\asdf.png" )
msgbox, errorlevel-%errorlevel% running test 5
run, mspaint
WinWait, untitled - Paint,
IfWinNotActive, untitled - Paint, , WinActivate, untitled - Paint,
WinWaitActive, untitled - Paint,
Send, ^o
send, c:\temp
send, {enter}
send, asdf.png
; result, Paint reports "file not found"
clipboard = %clip_save%
return
test 4 now looks like this (i found that if i clicked and dragged right to left the rectangle points would be 'wrong' for ScreenCapture and paint would give the error trying to paste from the clipboard.
Code:
#4:: ; test 4, use points captured by rhys' code, but put into a local variable first
clip_save = %clipboardall%
if rect_mx < %rect_mx_end%
{
top_x = %rect_mx%
top_y = %rect_my%
bot_x = %rect_mx_end%
bot_y = %rect_my_end%
}
else
{
top_x = %rect_mx_end%
top_y = %rect_my_end%
bot_x = %rect_mx%
bot_y = %rect_my%
}
;my_rect = %rect_mx%, %rect_my%, %rect_mx_end%, %rect_my_end%
my_rect = %top_x%, %top_y%, %bot_x%, %bot_y%
;msgbox, %my_rect%
capturescreen( my_rect, false, 0 )
;msgbox, errorlevel-%errorlevel% running test 4
run, mspaint
WinWait, untitled - Paint,
IfWinNotActive, untitled - Paint, , WinActivate, untitled - Paint,
WinWaitActive, untitled - Paint,
Send, {SHIFTDOWN}{INS}{SHIFTUP}{ENTER}
; result, Paint reports "Error getting the Clipboard data"
clipboard = %clip_save%
return