Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   FreePascal (https://www.delphipraxis.net/74-freepascal/)
-   -   Bild-Inhalt der Zwischenablage abspeichern? (https://www.delphipraxis.net/149537-bild-inhalt-der-zwischenablage-abspeichern.html)

Pascal95 23. Mär 2010 20:15


Bild-Inhalt der Zwischenablage abspeichern?
 
Hallo,

ich weiß, dass es dazu schon einige Beiträge im Forum gibt, doch bei funktioniert es nicht!
Wie der Titel sagt, möchte ich den Inhalt der Zwischenablage (Bitmap) abspeichern.

(SwissDelphiCenter.ch habe ich nicht verstanden)

Momentan habe ich die Funktion einen Screenshot zu machen so gelöst:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  keybd_event(VK_SNAPSHOT , 0, 0, 0);
  keybd_event(VK_SNAPSHOT , 0, KEYEVENTF_KEYUP, 0);
end;
Soweit klappt das auch. Ich kann das Bild in Paint einfügen. Nun möchte ich es aber automatisch speichern lassen.

if Clipboard.HasFormat(CF_BITMAP) then begin
Image1.Picture.Assign(Clipboard);
Image1.Picture.SaveToFile('C:\temp\screenshot.bmp' );
end;

klappt nicht: Fehlermeldung

Ich habe es auch mit

Delphi-Quellcode:
  Image1.Picture.Bitmap.Assign(Clipboard);
  Image1.Picture.Bitmap.SaveToFile('C:\temp\screenshot.bmp');
probiert.

Klappt alles nicht!

Würde mich freuen, wenn mir jemand helfen könnte. Ich finde hier im Forum und anderswo immer nur die obengenannte Funktion, die bei mir nicht klappt.

Ich benutze FreePascal Lazarus v0.9.28.2 Beta


Vielen Dank
Pascal95

alleinherrscher 23. Mär 2010 20:20

Re: Bild-Inhalt der Zwischenablage abspeichern?
 
Mach das ganze am besten ohne Zwischenablage:

http://www.delphipraxis.net/internal...t.php?t=123861

Wenn der Anwender während der Vorgangs zufällig was in die zwischenablage kopiert, is das mit deiner Methode nämlich nicht so toll, außerdem verliert der Benutzer möglicherweise andere Daten, die er in der zwischenabhlage hat.

Pascal95 23. Mär 2010 20:27

Re: Bild-Inhalt der Zwischenablage abspeichern?
 
Vielen Dank für die schnelle Antwort.

Jedoch habe ich den Sourcecode in mein Projekt kopiert und will ihn dann mit folgender Funktion aufrufen:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  GetScreenShot(Image1);
end;
Ich weiß allerdings auch nicht genau, wie die Syntax aussehen soll, also wie ich die Prozedur aufrufen soll.

Außerdem gibt diese Prozedur:
Delphi-Quellcode:
procedure GetScreenShot (var ABitmap : TBitmap);
var
  DC : THandle;
begin
  if Assigned(ABitmap) then                   // Check Bitmap<>NIL
  begin
    DC := GetDC();                            // Get Desktop DC
    try
      ABitmap.Width := Screen.Width;          // Adjust Bitmapsize..  
      ABitmap.Height := Screen.Height;        // ..to screen size
      BitBlt(ABitmap.Canvas.Handle,           // Copy
             0,0,Screen.Width,Screen.Height,  // Desktop
             DC,                              // into  
             0,0,                             // the
             SrcCopy                          // Bitmap
        );
    finally
      ReleaseDC(0, DC);                       // Relase DC
    end;
  end;
end;
... einige Errors:

unit1.pas(38,22) Error: Illegal parameter list
unit1.pas(40,11) Error: Wrong number of parameters specified for call to "GetDC"
unit1.pas(42,15) Error: Unknown record field identifier "WIDTH"
unit1.pas(43,15) Error: Unknown record field identifier "HEIGHT"
unit1.pas(44,22) Error: Unknown record field identifier "CANVAS"
unit1.pas(60,21) Error: Call by var for arg no. 1 has to match exactly: Got "TImage" expected "BITMAP"
unit1.pas(34,11) Hint: Found declaration: GetScreenShot(var BITMAP);
unit1.pas(88) Fatal: There were 6 errors compiling module, stopping

Warum funktioniert die Funktion nicht?
Das ist bei mir in der uses:
Delphi-Quellcode:
uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ExtCtrls, StdCtrls, Windows, CLipBrd, LCLIntf, LCLType;
Liegt es daran, dass cih mit Lazarus arbeite?

Vielen Dank
Pascal

alleinherrscher 23. Mär 2010 20:32

Re: Bild-Inhalt der Zwischenablage abspeichern?
 
Zitat:

Zitat von Pascal95

Liegt es daran, dass cih mit Lazarus arbeite?

Wahrscheinlich ja. Guck mal hier:

Zitat:

Ein Bildschirmfoto erstellen

Seit Lazarus 0.9.16 können sie die LCL verwenden um plattformunabhängig Bildschirmfotos aufzunehmen. Der folgende Beispielcode zeigt es (funktioniert unter GTK2 und Win32, aber gegenwärtig nicht unter GTK1):
Delphi-Quellcode:
  uses LCLIntf, LCLType;

  ...

var
  MyBitmap: TBitmap
  ScreenDC: HDC;
begin
  MyBitmap := TBitmap.Create;
  ScreenDC := GetDC(0);
  MyBitmap.LoadFromDevice(ScreenDC);
  ReleaseDC(ScreenDC);

  ...
aus: http://wiki.lazarus.freepascal.org/D...foto_erstellen

In deinem Fall würde ich es so umändern: Du hast ein Image1 auf dem Forumlar, und dann:

Delphi-Quellcode:
var ScreenDC:HDC;
begin
 ScreenDC:= GetDC(0);
 Image1.bitmap.loadFromDevice(ScreenDC);
 ReleaseDC(ScreenDC);
...

Pascal95 23. Mär 2010 20:38

Re: Bild-Inhalt der Zwischenablage abspeichern?
 
...Gibt wieder Errors:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var ScreenDC:HDC;
begin
ScreenDC:= GetDC(0);
Image1.Bitmap.loadFromDevice(ScreenDC);
ReleaseDC(ScreenDC);
end;
unit1.pas(39,8) Error: identifier idents no member "Bitmap"
unit1.pas(40,19) Error: Wrong number of parameters specified for call to "ReleaseDC"
unit1.pas(68) Fatal: There were 2 errors compiling module, stopping


Muss vielleicht
Delphi-Quellcode:
Image1.Bitmap.LoadFromDevice(ScreenDC);
durch
Delphi-Quellcode:
Image1.Picture.LoadFromDevice(ScreenDC);
ersetzt werden? Naja, das ergab dann diese Errors:

unit1.pas(39,16) Error: identifier idents no member "loadFromDevice"
unit1.pas(40,19) Error: Wrong number of parameters specified for call to "ReleaseDC"
unit1.pas(68) Fatal: There were 2 errors compiling module, stopping

Irgendwie kennt Lazarus "loadFromDevice" nicht...?

Vielleicht findest du oder jemand Anderes noch eine Lösung für mein Problem, auch wenn ich nicht mit der Zwischenablage arbeite, ich will nur den ganzen Bildschirm in eine bmp/png/jpg datei laden. Am besten bmp.


Pascal

alleinherrscher 23. Mär 2010 20:43

Re: Bild-Inhalt der Zwischenablage abspeichern?
 
sry, versuch es mal mit image1.picture.bitmap.LoadFromDevice

Was mit ReleaseDC los ist und welche Parameter das braucht weiß ich allerdings auch nicht. Gibts da nicht auch wie in delphi so eine Kontexthilfe wo angezeigt wird, was nun als parameter erwartet wird?

Pascal95 23. Mär 2010 20:48

Re: Bild-Inhalt der Zwischenablage abspeichern?
 
Moin,

jetzt hab ichs!!
Juhu.

Ich habe noch mal in meinen Archiven nachgeguckt und eben nur noch den ReleaseDc(ScreenDC); zu ReleaseDc(0, ScreenDC); geändert.
Mit folgendem Code funktioniert es wirklich super unter lazarus:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var ScreenDC:HDC;
begin
ScreenDC:= GetDC(0);
image1.picture.bitmap.LoadFromDevice(ScreenDC);
ReleaseDc(0, ScreenDC);
Image1.Picture.SaveToFile('C:\temp\screen.bmp');
end;
Vielen Dank. Hast mir sehr geholfen!

Pascal95


(erledigt)

alleinherrscher 23. Mär 2010 21:01

Re: Bild-Inhalt der Zwischenablage abspeichern?
 
Zitat:

Zitat von Pascal95
Vielen Dank. Hast mir sehr geholfen!

:) Kein Problem, dafür is das Forum ja da! :)

JamesTKirk 25. Mär 2010 19:44

Re: Bild-Inhalt der Zwischenablage abspeichern?
 
Hi!

Du hast zwar dein Problem bereits gelöst, dennoch möchte ich dir erklären, warum folgender Code nicht funktioniert hat:

Zitat:

Zitat von Pascal95
Außerdem gibt diese Prozedur:
Delphi-Quellcode:
procedure GetScreenShot (var ABitmap : TBitmap);
var
  DC : THandle;
begin
  if Assigned(ABitmap) then                   // Check Bitmap<>NIL
  begin
    DC := GetDC();                            // Get Desktop DC
    try
      ABitmap.Width := Screen.Width;          // Adjust Bitmapsize..  
      ABitmap.Height := Screen.Height;        // ..to screen size
      BitBlt(ABitmap.Canvas.Handle,           // Copy
             0,0,Screen.Width,Screen.Height,  // Desktop
             DC,                              // into  
             0,0,                             // the
             SrcCopy                          // Bitmap
        );
    finally
      ReleaseDC(0, DC);                       // Relase DC
    end;
  end;
end;
... einige Errors:

unit1.pas(38,22) Error: Illegal parameter list
unit1.pas(40,11) Error: Wrong number of parameters specified for call to "GetDC"
unit1.pas(42,15) Error: Unknown record field identifier "WIDTH"
unit1.pas(43,15) Error: Unknown record field identifier "HEIGHT"
unit1.pas(44,22) Error: Unknown record field identifier "CANVAS"
unit1.pas(60,21) Error: Call by var for arg no. 1 has to match exactly: Got "TImage" expected "BITMAP"
unit1.pas(34,11) Hint: Found declaration: GetScreenShot(var BITMAP);
unit1.pas(88) Fatal: There were 6 errors compiling module, stopping

Dein Problem ist hier, das der Typ Graphics.TBitmap, den du eigentlich verwenden wolltest, vom Record Windows.TBitmap, der ein Alias auf Windows.BITMAP ist, überschrieben wird. Das sieht man auch gut in deiner Uses:

Zitat:

Zitat von Pascal95
Das ist bei mir in der uses:
Delphi-Quellcode:
uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ExtCtrls, StdCtrls, Windows, CLipBrd, LCLIntf, LCLType;

Windows befindet sich hier hinter Graphics, weswegen alle Typen, die sowohl in der einen, als auch in der anderen Unit sind, sich komplett auf die hintere Unit beziehen. Du hättest eventuell auch in Lazarus mit gedrückter Strg-Taste auf TBitmap klicken können und er hätte dich womöglich an die "richtige" Deklaration in Windows geschickt - allerdings kann ich hier auch falsch liegen.

Und folgende Möglichkeiten hättest du gehabt den Fehler zu beseitigen:

1. du hättest aus jedem TBitmap ein Graphics.TBitmap gemacht
2. du hättest in deiner Unit TBitmap einfach als Alias auf Graphics.TBitmap definiert, also so:

Delphi-Quellcode:
type
  TBitmap = Graphics.TBitmap
Dadurch wäre der Windows-Typ mit dem richtigen Typ überschrieben worden.

3. du hättest du Reihenfolge der Units in der Uses anpassen können. Dies ist übrigens auch der Grund, warum Windows in Delphi :!: auch sehr weit vorne steht.
4. du hättest die Windows Unit ganz rauslassen können, da die benötigten Methoden eh durch LCLIntf und LCLType (eventuell auch noch LCLProc) eingebunden werden, allerdings kann ich diesen Punkt nicht mit Sicherheit bestätigen

Zitat:

Zitat von Pascal95
Liegt es daran, dass cih mit Lazarus arbeite?

Nein, das hätte dir auch mit Delphi passieren können ;)

Ich hoffe ich konnte dir etwas Klarheit verschaffen.

Gruß,
Sven

Pascal95 29. Mär 2010 17:11

Re: Bild-Inhalt der Zwischenablage abspeichern?
 
Danke auch dir Sven!

Pascal


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:19 Uhr.

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