Getting Cropper to work in Vista
UPDATE: A new version of Cropper with these changes has been released. Grab it here: http://blogs.geekdojo.net/brian/articles/Cropper.aspx
Summary
Cropper is my favorite screenshot utility, mainly because of the plugin support. It's not really usable in Vista because the graphics compositing changes in Vista cause problems with just BLT'ing from the desktop DC so the Cropper form is included in the captures. It's not simple, but you can decompile it, add 4 lines of code, and have a version of Cropper that works in Vista. There's talk of a new version of Cropper, but until then this will let you run Cropper 1.8 on Vista.
Confessions of a screenshot freak
I'm really into screenshot programs. I use them daily while writing a book, writing documentation, writing blog posts, and even OCR'ing screenshots of code. I regularly use several screenshot applications: WinSnap, the Vista Snipping Tool, TimeSnapper (not really a screenshot program; it's a desktop recorder), and Cropper.
Cropper is my favorite program, because it supports plugins like "Send to Flickr". (I've written a few myself, including a few I'm waiting to release until an official Vista version comes out).
The problem
Vista's window compositing system is radically new. I'm not going to pretend that I'm an expert on what's changed, but I do know that copying the desktop image (BitBlt from the Desktop HDC) has changed. The net result is that Cropper's translucent form shows up in the captured images (this image should be completely blank):
A cheesy solution
Step 1 - Decompile Cropper.exe
Cropper was originally distributed with the source, but for some reason the source hasn't been included with recent versions. It's not obfuscated, though, so you you can get the source in seconds with Reflector and Denis Bauer's File Disassembler plugin.
Step 2 - Modify TransparentCropForm.cs as follows:
private void TakeScreenShot(ScreenShotBounds bounds)
{
bool _currentlyVisibile = base.Visible;
this.highlight = true;
base.PaintLayeredWindow();
try
{
base.Hide();
switch (bounds)
{
case ScreenShotBounds.Rectangle:
if (this.isThumbnailed)
{
this.imageCapture.Capture(this.VisibleClientRectangle, this.maxThumbSize);
return;
}
break;
case ScreenShotBounds.ActiveForm:
this.imageCapture.CaptureForegroundForm();
return;
case ScreenShotBounds.FullScreen:
this.imageCapture.CaptureDesktop();
return;
case ScreenShotBounds.Window:
this.imageCapture.CaptureWindowAtPoint(Cursor.Position);
return;
default:
return;
}
this.imageCapture.Capture(this.VisibleClientRectangle);
}
catch (InvalidOperationException exception1)
{
TransparentCropForm.ShowError(exception1.Message, "Error Taking Screenshot");
return;
}
finally
{
if(_currentlyVisibile)
base.Show();
this.highlight = false;
base.PaintLayeredWindow();
}
}
Only 4 lines were added:
bool _currentyVisible = base.Visible;
base.Hide();
if(_currentlyVisible)
base.Show();
There are more elegant solutions, but they require changes to a lot more files and require passing references to user interface objects deep into the core DLL's. This solution is good enough for govm't work.
Step 3 - Recompile
This actually turned out to be the hardest part, since for some reason File Decompiler's csproj file had the resource references all confused. If you run into problems, contact me and I can send you my Cropper Vista Ghetto Build.