Is there a way to take a screenshot without purchasing a 3rd party plugin?
Thanks
Is there a way to take a screenshot without purchasing a 3rd party plugin?
Thanks
A Screenshot in Windows or Mac? or with a Xojo App ?
in OSX you can do
dim mshell as new Shell
mshell.Execute "screencapture -iW -o -P ~/Desktop/MyScreenshot.png"
Thanks for the replies. Both Windows and Mac.
I would like to avoid writing the screenshot to disk if possible. I would like to print it to picture var. I need to take many screenshots in a row, so the disk read/write would be a bottle neck.
Slow and manual answer:
a. Do the Clipboard screen shot,
b. Save the Clipboard contents to disk
c. Restart at a.
How do I do a screen shot using the OS default feature ?
OS X:
a. cmd-shift-ctrl-3 place the screen(s) into the Clipboard
b. cmd-shift-ctrl-4 allows you to choose a part of the screen and place it into the Clipboard
c. cmd-shift-ctrl-4 + space bar + a “later” click place the selected window contents (whole window with title bar, scroll bar, …) in the Clipboard
Windows (check on your machine to be sure, my memory may be wrong):
a. PrintScr put the whole screen(s) into the Clipboard
b. alt+PrintScr put the frontmost window content (with title bar,s croll bar, whatever) into the Clipboard.
There is also a delayed function to make screen shot(s), but it does not respect the HiDPI image valueÂ…
How do I save the Clipboard Picture contents to disk ?
Check these pages: Clipboard, Picture and FolderItem.
Dim Clip As New Clipboard
Dim Pict As Picture
If Clip.PictureAvailable Then
// Make here a copy of the Clipboard Picture
// Save here the Picture variable where the Clipboard image was saved to disk
End If
But, if you have many (tons) things to save, this will be a boring task.
What about using DrawInto ?
I never use it, so I cannot make comment.
MBS has a nice pluginset. It works pretty easy.
The screenshot function works on both mac and windows.
dim p as picture
p=screenshotRectMBS(self.left-5,self.top+35,self.width+10,self.height+20)
But of course that is a 3rd party plugin. But very worth purchasing though.
The other option is using declares. This code I found elsewhere on this forum:
const kCGWindowListOptionAll = 0
const kCGNullWindowID = 0
const kCGWindowImageDefault = 0
soft declare sub CGContextDrawImage lib "Carbon" (context as Ptr, rect as NSRect, image as Ptr)
soft declare function CGWindowListCreateImage lib "Carbon" (r as CGRect, windowList as integer, winID as integer, winImageOptions as integer) as ptr
dim s as CGRect = CGMakeRect(0,0,Screen(0).width, screen(0).height)
dim p as ptr = CGWindowListCreateImage(s, kCGWindowListOptionAll, kCGNullWindowID, kCGWindowImageDefault)
dim thePic as new Picture(s.w,s.h)
CGContextDrawImage ptr(thepic.Graphics.Handle(Graphics.HandleTypeCGContextRef)),s, p
This code renders a window you specify to memory. Not a screenshot.
Windows using declares:
Function CaptureRect(X As Integer, Y As Integer, Width As Integer, Height As Integer) As Picture
'Performs a screen capture on the specified screen rectangle.
#If TargetWin32 Then
Declare Function GetDesktopWindow Lib "User32" () As Integer
Declare Function GetDC Lib "User32" (HWND As Integer) As Integer
Declare Function BitBlt Lib "GDI32" (DCdest As Integer, xDest As Integer, yDest As Integer, Width As Integer, _
Height As Integer, DCdource As Integer, xSource As Integer, ySource As Integer, rasterOp As Integer) As Boolean
Declare Function ReleaseDC Lib "User32" (HWND As Integer, DC As Integer) As Integer
Const SRCCOPY = &h00CC0020
Const CAPTUREBLT = &h40000000
If Width = 0 Or Height = 0 Then Return Nil
Dim screenCap As Picture = New Picture(Width, Height, 24)
Dim HWND As Integer = GetDesktopWindow()
Dim SourceDC As Integer = GetDC(HWND)
Dim DestDC As Integer = screenCap.Graphics.Handle(screenCap.Graphics.HandleTypeHDC)
Call BitBlt(DestDC, 0, 0, Width, Height, SourceDC, X, Y, SRCCOPY Or CAPTUREBLT)
Call ReleaseDC(HWND, SourceDC)
Return screenCap
#Endif
End Function
Thanks Andrew. That worked great! Exactly what I was looking for.
Edwin- I tried the snippet, I’m getting a “Can’t find a type with this name” for NSRect. Is that part of an old library?
Edwins Code is incomplete.
for a screenshot into clipboard
with selection tool
dim mshell as new Shell
mshell.Execute "screencapture -i -c"
selected Window
dim mshell as new Shell
mshell.Execute "screencapture -iW -o -c"
Hello all
I tried the code supplied by Andrew and it works great. I do have an extra question: how can I show the cursor because it is not showing now.
Thanks
Richard
The system does not capture the cursor. This is what I did to have the cursor captured when I click on a window, and the result appears as the backdrop of that window. The same principle can be used to capture the cursor elsewhere.
I have use a 16x16 icon from http://www.fatcow.com/free-icons called appropriately cursor.png.
Function MouseDown(X As Integer, Y As Integer) As Boolean
self.backdrop = CaptureRect(me.left,me.top,me.width,me.height)
End Function
In MouseEnter :
Sub MouseEnter()
App.MouseCursor = System.Cursors.InvisibleCursor
End Sub
In MouseExit :
Sub MouseExit()
App.MouseCursor = System.Cursors.InvisibleCursor
Canvas2.Top = -100
End Sub
In MouseMove :
Sub MouseMove(X As Integer, Y As Integer)
Canvas2.top = Y
Canvas2.left = X
End Sub
The way it works, in MouseEnter I make the cursor invisible. Then in MouseMove, I have the Canvas2 follow X and Y. When MouseDown occurs, BitBlt inside teh CaptureRect grabs the picture of the canvas instead of the cursor. In MouseExit, I put the Canvas2 back off window, invisible.
You can also use the Canvas visible property.
Thinking about it, the method I posted works only to grab the cursor over the app window. Here is an idea I did not test yet, but it should work.
If one wanted to get a cursor image over the entire screen, the solution would be to create a transparent window with the same technique as /Example Projects/Platform-Specific/Windows/CustomWindowShape with the same cursor image making sure that the white inside the arrow is actually all so lightly grey. Actually RGB(254,254,254) would do the trick.
Then use a timer to monitor System.MouseX and System.MouseY to position the small cursor window under the mouse cursor. If the window is not perfectly aligned to the cursor, it will probably look kind of odd, like seeing cursor double. But when the screen is grabbed, only the cursor window will show.
The thorny thing is, if the app loses front, the false cursor will stop moving. So that cannot be used to grab the screen while clicking elsewhere.
Another solution is to use System.MouseX and Y to DrawPicture the cursor in the grabbed image at the proper place.
Here’s an updated version that asks Windows to draw the current cursor icon into the picture at the current mouse coordinates. In my testing it’s a few pixels off, though:
[code]Function CaptureRect(X As Integer, Y As Integer, Width As Integer, Height As Integer) As Picture
'Performs a screen capture on the specified screen rectangle.
#If TargetWin32 Then
Declare Function GetDesktopWindow Lib “User32” () As Integer
Declare Function GetDC Lib “User32” (HWND As Integer) As Integer
Declare Function BitBlt Lib “GDI32” (DCdest As Integer, xDest As Integer, yDest As Integer, Width As Integer, _
Height As Integer, DCdource As Integer, xSource As Integer, ySource As Integer, rasterOp As Integer) As Boolean
Declare Function ReleaseDC Lib “User32” (HWND As Integer, DC As Integer) As Integer
Const SRCCOPY = &h00CC0020
Const CAPTUREBLT = &h40000000
If Width = 0 Or Height = 0 Then Return Nil
Dim screenCap As Picture = New Picture(Width, Height, 24)
Dim HWND As Integer = GetDesktopWindow()
Dim SourceDC As Integer = GetDC(HWND)
Dim DestDC As Integer = screenCap.Graphics.Handle(screenCap.Graphics.HandleTypeHDC)
Call BitBlt(DestDC, 0, 0, Width, Height, SourceDC, X, Y, SRCCOPY Or CAPTUREBLT)
Call ReleaseDC(HWND, SourceDC)
//ADDED CODE STARTS HERE
Declare Function GetCursorInfo Lib "User32" (CursorInfo As Ptr) As Boolean
Declare Function DrawIcon Lib "User32" (hDC As Integer, X As Integer, Y As Integer, hIcon As Integer) As Boolean
Const DI_MASK = &H1
Dim cursorinfo As New MemoryBlock(20) ' A CURSORINFO structure
cursorinfo.Int32Value(0) = cursorinfo.Size
If Not GetCursorInfo(cursorinfo) Then Return Nil
Dim hCursor As Integer = cursorinfo.Int32Value(8) ' current cursor handle
If Not DrawIcon(DestDC, System.MouseX - X, System.MouseY - Y, hCursor) Then Return Nil
//End added part
Return screenCap
#Endif
End Function
[/code]
[quote=224590:@Axel Schneider]selected Window
dim mshell as new Shell
mshell.Execute “screencapture -iW -o -c”[/quote]
Can this be done non-interactively, (automatically, since the window would have already been selected)?
I have not seen that on the manpage.
Thanks.
Lennox
Unfortunately the clipboard is bugged in the Windows version of Xojo2017, pasting the image to a pictureviewer only shows a white rectangle. I tried it in Xojo 2016r2.1 and there it works just fine.
The case is set to Private or do not exists.
it’s only for beta testers