7

Assuming I would like to program a magnifier, how could I capture the content of the screen excluding my very own window ? I know how to capture the screen with my own window using BitBlt and the Desktop DC.

And to make it clearer: I want to show the magnified content in my window.

Edit: It seems that there is no other solution than to hide my window (or the client area) one way or another before I can capture the screen content under my window. Apparently this causes my window to flicker which renders this scenario pretty useless.

iamjoosy
  • 3,299
  • 20
  • 30

4 Answers4

2

During the capture process set the forms AlphaBlend property to true and the AlphaBlendValue to 0. Be aware that this will make your form completely invisible.

Uwe Raabe
  • 45,288
  • 3
  • 82
  • 130
  • Thanks Uwe, Unfortunately this causes my window to flicker (e.g. when done from within a timer event). So given my original scenario (the magnifier) this doesn't really work. – iamjoosy Jun 27 '11 at 16:27
  • 1
    If you set the AlphaBlendValue to just under the maximum, that will force Windows to render the content underneath the window but still leave the window nearly unchanged. The problem is how to capture that underneath portion? – Mark Ransom Jun 27 '11 at 17:30
1

You use PrintWindow() for that, but it is not fast and does not work for all applications.

Mike Versteeg
  • 1,615
  • 14
  • 28
  • Mike, I don't want to capture my own window, but what is under my own window. – iamjoosy Jun 27 '11 at 16:34
  • @iamjoosy, first you locate the window that is under your own window, then you call PrintWindow with that HWND. He's right that it will be hit and miss whether it works. – Mark Ransom Jun 27 '11 at 17:07
  • @Mark, but there might not be only one window under my own window, but many, partially overlapping, or just the desktop. Remember from my question, what I want to do is a magnifier, that magnifies whatever is under my window. – iamjoosy Jun 27 '11 at 17:13
  • 1
    @iamjoosy, what you want is irrelevant if it's impossible. In this case it might be, and you'll have to settle for a less than perfect solution, this being one of them. Good luck. – Mark Ransom Jun 27 '11 at 17:28
1

You need to capture the screenshot from the DC of the desktop, into a bitmap in memory.

procedure CaptureScreenShot(acapture: TBitMap);
 var c: TCanvas;
     r: TRect;
 begin
  c:= TCanvas.Create;
  c.Handle:= GetWindowDC (GetDesktopWindow);
  try
    r:= Rect(0,0,screen.width,screen.height);
    acapture.Width:=screen.Width;
    acapture.Height:=screen.Height;
    acapture.Canvas.CopyRect(r, c, r);
  finally
    ReleaseDC(0, c.handle);
    c.Free;
  end;
end;

Add to this Uwe's answer to make your form invisible and you have....

FCapturedScreenShot:TBitmap;
....
FCapturedScreenShot:=TBitmap.Create;
....
AlphaBlend:=true;
AlphaBlendValue:=0; 
CaptureScreenshot(FCapturedScreenShot);
AlphaBlendValue:=False; 

use the captured screenshot for whatever you need, you might assign it over a bitmap in another form, or save it in an array of captured screens...

PA.
  • 28,486
  • 9
  • 71
  • 95
  • Thanks PA. Note, that I don't want to capture the complete screen. I edited my question to make this clearer. In addition the solution from Uwe doesn't really work as this causes my window to flicker. – iamjoosy Jun 27 '11 at 17:04
  • @iamjoosy, just capture the whole desktop and cut out rectangle under your magnifier window. – andrius Jun 27 '11 at 17:23
0

Try to minimize or hide you form before capture the screen and restore or show the form after capture screen

Mahdi
  • 247
  • 2
  • 6