Re: Capturing windows in an NSImage
Re: Capturing windows in an NSImage
- Subject: Re: Capturing windows in an NSImage
- From: Andrew Farmer <email@hidden>
- Date: Wed, 19 Jul 2006 19:08:35 -0700
On 19 Jul 06, at 14:31, Eric Summers wrote:
I'm trying to figure out how programs like Apple's Grab screen capture
application get an image of other application windows. I thought
of using
an AppleEvent to get the bounds of the windows then capturing the
data using
a big transparent window, but that wouldn't work if the window is
hidden.
Grab will get the image data even if the window is hidden. Anyone
know how
the Grab application works?
Yes!
http://www.objective-cocoa.org/forum/index.php?topic=1556.msg15898
The post is in French; here's a copy of the code and a translation of
the
comments, for the list archive and the non-Francophones in the crowd:
NSImage *GrabWindow(int wid)
{
// Get a context-ID
int cid = [NSApp contextID];
// Get the coordinates of the window
CGRect cgrect;
CGSGetWindowBounds(cid, wid, &cgrect);
// Transform CGRect to NSRect
NSRect nsrect;
nsrect.origin.x = cgrect.origin.x;
nsrect.origin.y = cgrect.origin.y;
nsrect.size.width = cgrect.size.width;
nsrect.size.height = cgrect.size.height;
// Create an NSImage
NSImage *img = [[NSImage alloc] initWithSize:nsrect.size];
// Write to the graphical context of the image
[img lockFocus];
// Get the grafport for the image
void *grafport = [[NSGraphicsContext currentContext] graphicsPort];
// Copy the contents of the window to the graphic context
cgrect.origin = CGPointZero;
CGContextCopyWindowCaptureContentsToRect(grafport, cgrect, cid,
wid, 0);
// Release the graphic context
[img unlockFocus];
// End of procedure: return the image
return [img autorelease];
}
Note that this invokes a couple of private functions:
OSStatus CGSGetWindowBounds(int cid, int wid, CGRect *ret);
void CGContextCopyWindowCaptureContentsToRect(void *grafport, CGRect
rect,
int cid, int wid, int zero);
No, I don't know what the last parameter is for. The only program I
know of
that uses CGCWCCTR - screencapture - always passes a constant zero
for the
last argument.
There's also another useful function that gets invoked in the
screencapture
tool:
OSStatus CGSFindWindowByGeometry(int cid, int zero, int one, int
zero_again,
CGPoint *screen_point, CGPoint *window_coords_out,
int *wid_out, int *cid_out);
This'll take a point in screen coordinates, specified by
screen_point, and
return the window ID of the frontmost window at that point (in
wid_out), the
WindowServer connection ID of that application (in cid_out), and the
transformed coordinates of that point within the window (in
window_coords_out).
There's actually no public *or* private API for the "click to select
a window"
interface that you get in screencapture; the tool just creates
translucent
overlay windows itself.
(Google actually isn't aware of any prior documentation for this
function.)
Oh, and remember that these are highly private interfaces. They will
probably
break on OS updates, particularly big ones. Don't complain to Apple
when they
do.
Attachment:
PGP.sig
Description: This is a digitally signed message part
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden