Solved

Screen Shto based on Window location and size

Posted on 2003-11-28
21
682 Views
Last Modified: 2012-05-04

I need some code that will take a screen shot in the following manner.

1- I want my application window to be the size of the screen shot
2- when I move my window to any area of the desktop I want to to take a new screen shot of the desk top and display it on my form. (The Form Drag  shold trigger the new screen shot)
3- The screenshot should be the size of just my window and the desktop directly under my window only (not the entire desktop)
4- The screenshot area should be adjustable based on the size of the window of my application minus the title bar of my window. (If I re-size my window the screen shot area should increase).

I have pieces working, but cant get it all together. 300 pts for a clean working solution
0
Comment
Question by:quantum2
  • 8
  • 5
  • 4
  • +3
21 Comments
 
LVL 7

Expert Comment

by:sftweng
ID: 9841411
See id: 16283 "Capture and enlarge an area of the Windows desktop" at http://codecentral.borland.com
0
 
LVL 1

Author Comment

by:quantum2
ID: 9841821
What I am looking for is some Delphi 5 code that will do the following:

When my application window appears on the screen, it immediately takes a screen shot of the desktop area directly underneath my window and then displays it on its form.

The screen shot needs to be just what is behind my window and nothing more, so think of it as taking a screen shot via a region, except the form width-height and location are defining the region of the screen shot to be taken. Then the image is displayed in a TImage on the form.

A Drag event causing the window to move would trigger a new screenshot when the window was no longer being dragged.

Upped the points to 500 for Delphi 5 code that will do this.
0
 
LVL 7

Expert Comment

by:sftweng
ID: 9842577
The example I pointed to does almost exactly that, the differences I can see are that it allows magnification of the underlying screen and allows you to reposition the logical window from which it takes the snapshot without having to move the application's form. Have you had a look at the code and run the example?
0
 
LVL 3

Expert Comment

by:Mamouri
ID: 9842937
Hi!
I know what you want to do! You want write a program like SnagIt (capture Object or window) or HyperSnap DX, etc!

Just see following question:
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20628408.html

And this one:
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20794884.html

Regards
0
 

Expert Comment

by:DavidZhou
ID: 9844338
the code below snap the screen to Tempbmp.

var
  ScrDC : HDC;
  TempBmp : TBitmap ;
begin
  ScrDC := GetDC(0);
  BitBlt(TempBmp.Canvas.Handle,0,0,Screen.Width,Screen.Height,ScrDC,0,0,SRCCOPY);
  ReleaseDC(ScrDC);
end;
0
 
LVL 1

Author Comment

by:quantum2
ID: 9844709
Mamouri,
Actually, I am trying to do something completely different and the screenshot is only a means to an end. That thread you gave me is informative, and I can hack something from it. I figured there would be an easier solution.

David' code works fine for getting the screen shot of the entire screen, however, what I am after is limiting the screen shot taken (much like drawing a rectangle) to the physical dimensions and location of my form on the desktop. Once I have that screenshot for that specific area I will be off and to the races.

Sftweng - I will go look at the code again. I dont have Delphi 6 so I would have to convert anything that doesnt work in 5 backwards so I can compile it.

Certainly there is an easier way of obtaining a screen shot by taking the top and left property of the form as well as its physical width and height to draw a rectangle and then grab the screen shot under the form. (notice the tricky part here is not getting a screen shot of the form itself) and then putting that image in a TImage on my own form.

Q2

Q2
0
 
LVL 5

Expert Comment

by:delphized
ID: 9844761
if you dont' have components on your form, you could just "cut" the region of the form leaving only the bordes. In this way your user can resize and see what there is underneath. (if youneed code tell me).

bye
0
 
LVL 1

Author Comment

by:quantum2
ID: 9844792
Delphized,
Tell you what. Now you are on to something, but once I get the screen shot, I would need the cliped region back as a form so I could display the screen shot.

How about this (700 pts to the first who gives me sample code)

1- On the form create, read from an INI file (or registry) the location and size of the window.
2- Take a screen shot (regional screen shot) based on that location and dimension
3- Display the form with the screen shot in a TImage on the form (should fit exaclty on form (client wideth and height))
4- On form move, when the mouse is let go, re-snap the screen shot based on the new location and refresh the background of the form.

The goal here is to always have a screen shot of the desktop of what would be right under "My" form

700 Pts for working Delphi 5 code.

Q2
0
 
LVL 5

Expert Comment

by:delphized
ID: 9844796
so you have components on this form? you want to make like a gosth? do you need to save the image for future use or not?
0
 
LVL 1

Accepted Solution

by:
roknjohn earned 400 total points
ID: 9846677
Why not just make the form transparent?

This code below (taken from delphi.about.com) creates a transparent form with a button (Button1).  You should be able to adapt it if you have multiple controls on your form.

procedure TForm1.FormCreate(Sender: TObject) ;
var
   FullRgn, ClientRgn, ButtonRgn: THandle;
   Margin, X, Y: Integer;
begin
   Margin := (Width - ClientWidth) div 2;
   FullRgn := CreateRectRgn(0, 0, Width, Height) ;
   X := Margin;
   Y := Height - ClientHeight - Margin;
   ClientRgn := CreateRectRgn
     (X, Y, X + ClientWidth, Y + ClientHeight) ;
   CombineRgn(FullRgn, FullRgn, ClientRgn, RGN_DIFF) ;

  //exclude the form's controls here
   X := X + Button1.Left;
   Y := Y + Button1.Top;
   ButtonRgn := CreateRectRgn
     (X, Y, X + Button1.Width, Y + Button1.Height) ;
   CombineRgn(FullRgn, FullRgn, ButtonRgn, RGN_OR) ;

   SetWindowRgn(Handle, FullRgn, True) ;
end;

0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 1

Author Comment

by:quantum2
ID: 9846719
Delphized,
It isnt so much that it is a ghost. What I need is a screen shot of the area that would be behind the form. Then I can take that area and display it on the form. So, Think of it as taking the position of the form and its dimensions and using that information to take a screen shot before the form is displayed. Then on the form create, take that image and display it in a TImage as the form is created. Then, if the form is moved. The form will go blank, allow the move and then take a new screen shot based on its new location. Then I can redraw the form with whatever controls on it I need. In the initial display, I can make all the controls invisible then once I get the screen shot, add them to the form.

RoknJohn,
Interesting code. I will have to give it a shot. However there is a reason why I need the screen shot. It isnt that I need a transparent form so much, I do need the screen shot. The transparent code here would work as the form displays is moved and then the screenshot is taken. Then I can make the form opaque and display the screenshot. The idea here is that I get a canvas which has an image of the desktop that I can manipulate once I am done. That is why I need the screen shot.


Q2
0
 
LVL 7

Assisted Solution

by:sftweng
sftweng earned 100 total points
ID: 9846879
Now we're really cooking! Here's some code (doesn't include Registry settings). The trick is to put the image into which the capture is done into a separate invisible form. This program copies the screen to the image and then assigns it to the clipboard. If you really want to get invisible, set Form1.BorderStyle to bsNone. Thanks roknjohn for the invisibility tip.

unit ScreenCaptureMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Clipbrd, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure MakeTransparent;
    procedure CopyImageToClipboard;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  ScreenCaptureImageForm;

{$R *.dfm}

procedure TForm1.CopyImageToClipboard;
var
  screenDC: HDC;
  imageRect : TRect;
  imageWidth, imageHeight: integer;
  screenLeft, screenTop : INTEGER;
begin
  MakeTransparent;
  screenDC    := GetDC(0);
  screenLeft  := Form1.ClientOrigin.X;
  screenTop   := Form1.ClientOrigin.Y;
  imageWidth  := Form1.ClientWidth;
  imageHeight := Form1.ClientHeight;
  if (screenDC > 0) then WITH ImageForm DO begin
    try
      Image1.Width  := imageWidth;
      Image1.Height := imageHeight;
      BitBlt(Image1.Canvas.Handle,
             Image1.Left, Image1.Top, imageWidth, imageHeight,
             screenDC, screenLeft, screenTop, SRCCOPY);
      ClipBoard.Assign(Image1.Picture);
    finally
      ReleaseDC(0,screenDC);
    end;
  end;
end;

procedure TForm1.MakeTransparent;
var
   FullRgn, ClientRgn, ButtonRgn: THandle;
   Margin, X, Y: Integer;
begin
   Margin := (Width - ClientWidth) div 2;
   FullRgn := CreateRectRgn(0, 0, Width, Height) ;
   X := Margin;
   Y := Height - ClientHeight - Margin;
   ClientRgn := CreateRectRgn
     (X, Y, X + ClientWidth, Y + ClientHeight) ;
   CombineRgn(FullRgn, FullRgn, ClientRgn, RGN_DIFF) ;

  //exclude the form's controls here
   X := X + Button1.Left;
   Y := Y + Button1.Top;
   ButtonRgn := CreateRectRgn
     (X, Y, X + Button1.Width, Y + Button1.Height) ;
   CombineRgn(FullRgn, FullRgn, ButtonRgn, RGN_OR) ;

   SetWindowRgn(Handle, FullRgn, True) ;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MakeTransparent;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CopyImageToClipboard;
end;

end.

unit ScreenCaptureImageForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
  TImageForm = class(TForm)
    Image1: TImage;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  ImageForm: TImageForm;

implementation

{$R *.dfm}

end.
0
 
LVL 1

Expert Comment

by:roknjohn
ID: 9846883
well then, you can use the transparent form as I mentioned.  Then, whenever you need the bitmap, just do a BitBlt from the desktop image, like this:

function GetFormBitmap(Form : TForm) :TBitmap;
var
  Desktop:HDC;
begin
  Result:= TBitmap.Create;
  Desktop:= GetDC(0);
  try
  try
    Result.PixelFormat:=pf32bit;
    Result.Width:=Form.Width;
    Result.Height:=Form.Height;
    BitBlt(Result.Canvas.Handle,0,0,Result.Width,Result.Height,Desktop,Form.Left,Form.Top,SRCCOPY);
    Result.Modified:=True;
  finally
    ReleaseDC(0,Desktop);
  end;
  except
    Result.Free;
    Result:=nil;
  end;
end;

You can trim out the title and borders if not needed, pretty easily.  
0
 
LVL 1

Expert Comment

by:roknjohn
ID: 9846897
oops, it looks like sftweng and I were posting at the same time.  The clipboard concept is a novel one, but I dont think it is really needed.  Just do a Image1.Picture.Bitmap.Assign(GetFormBitmap(Self));
0
 
LVL 1

Author Comment

by:quantum2
ID: 9846906
Hey guys...
Now it looks like I have something to work with. I am going to go try this today/tonight. I will award points this evening if this works like it appears it will.

RoknJohn, I will send 100 your way for the help.

I really appreciate it

Q2
0
 
LVL 1

Author Comment

by:quantum2
ID: 9846913
John,
Excellent point, I can assign on the fly.

I really appreciate it !!

Q2

0
 
LVL 7

Expert Comment

by:sftweng
ID: 9846914
I believe that roknjohn should get the lion's share of the points.
0
 
LVL 1

Expert Comment

by:roknjohn
ID: 9846919
thanks, those will be my first. can i cash them in for cash and fabulous prizes? :-)
0
 
LVL 1

Author Comment

by:quantum2
ID: 9848915
Hey Guys...
The transparent code works great. However, I cant get the screen shot to work at all. Man Delphi 5 pukes hard on the assigning of the image. Did you write this in Delphi 5..?

Perhaps sending me your little project would help. I could have sworn I got this right. I did a DIFF on the code and they are identical.... so I have no idea what I have done wrong.

The form is transparent when it displays though.

If you want to send the source files email them to:
junkmail@2amsolutions.com

Thanks

Q2
0
 
LVL 7

Expert Comment

by:sftweng
ID: 9848959
Q2, I have sent you a zip file with the project. In the version I have sent, it's slightly extended to use keystrokes to trigger border visibility/invisibility and screen capture to the clipboard. This was developed with Delphi 6. I've included the EXE file.
0
 
LVL 1

Author Comment

by:quantum2
ID: 9849143
roknJohn
I owe you another 200 pts and I am giving Sfteng another 100. You two go find two new questions as labeled:

Points for Roknjohn
Points for sftweng

and just respond. I will then award the additional points.

You guys have been great.

Thanks

Q2
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now