Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Screenshot, ohne das eigene Fenster drauf ist. (https://www.delphipraxis.net/90745-screenshot-ohne-das-eigene-fenster-drauf-ist.html)

Evian 23. Apr 2007 09:19


Screenshot, ohne das eigene Fenster drauf ist.
 
Hallo Zusammen,

ich möchte auf einem Formular einen Teil-Screenshot des Bildschirms anzeige und zwar genau den Bereich, der sich unter meinem Formular befindet. Außerdem soll dieser Screenshot relativ häufig aktualisiert werden. Problem dabei ist, wenn mein Formular wärend des Screenshots sichtbar ist, dann ist es aber auch Teil des Screenshots, was ja Sinn der Sache ist.
Das Mitglied TurboPascal hat mir gesagt, dass ich mein Vorhaben mit CreateRectRgn & CombineRgn & SetWindowRgn bewerkstelligen könnte, konnte mir auch aus Zeitgründen erstmal nicht weiter helfen. Da ich bisher nicht genau verstehe, wie diese API-Funktionen arbeiten und wie ich sie für mein Vorhaben nutzen könnte, wollte ich mal hier fragen, ob mir jemand von euch das erklären könnte. Ein kleines Code-Beispiel wäre super!

vielen Dank,

Evian

Namenloser 23. Apr 2007 09:28

Re: Screenshot, ohne das eigene Fenster drauf ist.
 
Ich hab für diesen Zweck das Formular halbtransparent gemacht, und komischerwiese war es auf dem screenshot nicht zu sehn. Du könntest ja das alphablend des formulars auf 254 stellen, wobei das natürlich keine sonderlich elegante Lösung ist...

Evian 23. Apr 2007 09:41

Re: Screenshot, ohne das eigene Fenster drauf ist.
 
Naja funktioniert auch nicht. Auch wenn Alphablending an und der das Value auf 254 steht, wird das Fenster mit angezeigt. Wäre aber auch unlogisch gewesen, wenn nicht. Also es wäre echt super, wenn es irgendwo ein Tutorial für den Umgang mit CreateRectRgn & CombineRgn & SetWindowRgn geben würde.

_frank_ 24. Apr 2007 00:19

Re: Screenshot, ohne das eigene Fenster drauf ist.
 
warum so kompliziert?

Delphi-Quellcode:
formx.hide;
makescreenshot;
formx.show;
hat bei mir damals wunderbar funktioniert ;)

Gruß Frank

Olli 24. Apr 2007 01:30

Re: Screenshot, ohne das eigene Fenster drauf ist.
 
Zitat:

Zitat von _frank_
warum so kompliziert?

Delphi-Quellcode:
formx.hide;
makescreenshot;
formx.show;
hat bei mir damals wunderbar funktioniert ;)

Benutze ich in EDA auch, funzt nur leider nicht immer. :| ... scheint deutlich von der Systemauslastung abzuhaengen.

http://assarbad.net/stuff/eda_previe...2003-10-12.rar

Evian 24. Apr 2007 08:29

Re: Screenshot, ohne das eigene Fenster drauf ist.
 
Zitat:

Zitat von _frank_
Delphi-Quellcode:
formx.hide;
makescreenshot;
formx.show;

Naja es müssen zwichen 16 und 25 Teilscreenshots pro Sekunde gemacht werden und wenn ich davor jeweils die Form hide, dann fänngt das ganze an, ordentlich zu flackern.

_frank_ 24. Apr 2007 09:09

Re: Screenshot, ohne das eigene Fenster drauf ist.
 
ich weis nicht, was du genau realisieren willst, aber denke, dass screenshots (zumindest in diesen Ausmaßen) keine gute Wahl sind.
Was genau hast du vor (wie soll es aussehen)?
willst du ein nicht rechteckiges form oder z.B. "Löcher" im Form, dann regions,
wenn der Hintergrund durchscheinen soll, dann alphablending.

Gruß Frank

Evian 24. Apr 2007 09:26

Re: Screenshot, ohne das eigene Fenster drauf ist.
 
Ich arbeite an einer kleinen Bildschirmlupe. Bisher habe ich bei Programmstart einen Screenshot gemacht, von dem die entsprechenden Teile vergrößert auf dem Hauptformular dargestellt wurden und wenn der Benutzer mit der Maus klickt, wird die Lupe wieder beendet. Das funktioniert bei sich nicht verändernden Bildschirminhalten ganz gut, aber bei bewegten Bildern (z.B. Videos oder Auftreten von Events, die den Bildschirminhalt verändern) versagt die Lupe, da nach einer Änderung kein neuer Screenshot gemacht wird und man quasi mit der Lupe nur die "Vergangenheit" sieht.

Ich habe jetzt aber eine andere Lupe gesehen, bei der auch bewegte Bilder vergrößert werden können. Und diese Lupe arbeitet mit CreateRectRgn & CombineRgn & SetWindowRgn.

Naja das verknüpfen des Desktops mit meiner Form habe ich schon geschafft:

Delphi-Quellcode:
VAR
  region1, region2: hrgn;
begin
  region1 := CreateRectRgn(0, 0, Width, Height);
  region2 :=  CreateRectRgn(10, 10, Width - 10, Height -10);
  CombineRgn(region1, region1, region2, RGN_DIFF);
  SetWindowRgn(Handle, region1, True);
end;
... aber ich weiß nicht, wie ich das jetzt vergrößert darstellen kann.

Olli 24. Apr 2007 10:08

Re: Screenshot, ohne das eigene Fenster drauf ist.
 
Zitat:

Zitat von Evian
Ich arbeite an einer kleinen Bildschirmlupe. Bisher habe ich bei Programmstart einen Screenshot gemacht, von dem die entsprechenden Teile vergrößert auf dem Hauptformular dargestellt wurden und wenn der Benutzer mit der Maus klickt, wird die Lupe wieder beendet. Das funktioniert bei sich nicht verändernden Bildschirminhalten ganz gut, aber bei bewegten Bildern (z.B. Videos oder Auftreten von Events, die den Bildschirminhalt verändern) versagt die Lupe, da nach einer Änderung kein neuer Screenshot gemacht wird und man quasi mit der Lupe nur die "Vergangenheit" sieht.

Nur mit einem Mirrortreiber bekommst du es wirklich hundertprozentig live. Bei Videos gibt es ohnehin das Problem, dass es in den meisten Faellen einfach eine pinke Flaeche sein wird - es sei denn du schaltest die Hardwarebeschleunigung komplett aus, wodurch selbst moderne Rechner bei Videos manchmal ins Stottern kommen.

Behelfsweise kann man statt des Treibers wie beim RealVNC auch ein paar Fensterhooks setzen. Da es sich um quelloffene Software handelt, kannst du dir zumindest was abgucken. Solange du es nicht kopierst, hat die GPL ja keine Bedeutung fuer dich.

turboPASCAL 24. Apr 2007 10:09

Re: Screenshot, ohne das eigene Fenster drauf ist.
 
Zitat:

Zitat von _frank_
warum so kompliziert?

Delphi-Quellcode:
formx.hide;
makescreenshot;
formx.show;
hat bei mir damals wunderbar funktioniert ;)

Gruß Frank

Ist recht unsicher, das Fenster (die Form) versteckt ja nicht Delphi sondern Windows.
Ist das System ausgelastet oder hat noch keine Lust dazu kann es passieren das der
Screenshot schneller aufgerufen wird als die gesendete Message vom Programm an Win. das
Fenster zu "verstecken".

Am besten ist wohl in diesem Falle vorhrer zu Prüfen ob das Fenster sichtbar bzw. nicht sichtbar ist.

Code:
procedure FormXYZ.
begin
  FormX.Hide;
  while IsWindowVisible(Self.Handle) {und /oder Timelimit erreicht} do
    Application.ProcessMessage;
  MakeScreenShot;
  FormX.Show;
end;
Mit einer Windowsregion schaut das ungf. so aus:

Delphi-Quellcode:
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons, ExtCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  private
    { Private-Deklarationen }
    bmp: TBitmap;
    procedure WMNCHitTest(var aMessage: TWMNCHitTest); message WM_NCHITTEST;
    procedure WMWindowPosChanging(var aMessage: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;
    procedure WMEraseBkgnd(var aMessage: TWMEraseBkgnd); message WM_ERASEBKGND;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

var
  Rgn : HRGN;

function CreateRgnFromRect(ARect: TRect): HRGN;
begin
  Result := CreateRectRgn(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  bmp := TBitmap.Create;
  bmp.PixelFormat := pf24Bit;
  bmp.Width := Self.ClientWidth;
  bmp.Height := Self.ClientHeight;

  Rgn := CreateRgnFromRect(Self.ClientRect);
  SetWindowRgn(Handle, Rgn, TRUE);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  bmp.Free;
end;

procedure TForm1.WMNCHitTest(var aMessage: TWMNCHitTest);
var
  p : tpoint;
begin
  inherited;

  p.x := aMessage.XPos;
  p.y := aMessage.YPos;
  p := screenToClient(p);

  if PtInRect(Self.Clientrect, p) then
   aMessage.Result := HTCAPTION;
end;

procedure TForm1.WMWindowPosChanging(var aMessage: TWMWindowPosChanging);
var
  ScrDC: HDC;
  p: TPoint;
begin
  inherited;

  if isWindowVisible(Self.Handle) then
  begin

  p.x := aMessage.WindowPos.x;
  p.y := aMessage.WindowPos.y;

  bmp.Canvas.Brush.Style := bsSolid;
  bmp.Canvas.Pen.Color := clGreen;
  bmp.Canvas.FillRect(Self.Clientrect);

  // Screen to Bitmap
   ScrDC := GetDC(0);
    BitBlt(
        bmp.Canvas.Handle,
        0,
        0,
        bmp.Width,
        bmp.Height,
        ScrDC,
        p.x,
        p.y,
        SRCCOPY
      );
    ReleaseDC(0, ScrDC);

    Self.Paint;
  end;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  if isWindowVisible(Self.Handle) and Assigned(bmp) then
    Self.Canvas.Draw(0,0, bmp);
end;

procedure TForm1.WMEraseBkgnd(var aMessage: TWMEraseBkgnd);
begin
  aMessage.Result := 0;
end;

end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:24 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz