Entwickler-Ecke

Windows API - Ruckler bei Screenshot machen


lemming - Di 30.07.02 10:10
Titel: Ruckler bei Screenshot machen
Hallo!

Ich habe in meinem Programm unangenehme Ruckler (so ca. 1/2 Sekunde) wenn das selbe einen Screenshot macht. Gibts da nicht ne Anweisung die dem System anweist weiter zu machen?


wwerner - Di 30.07.02 10:21

Wie machst du den den ScreenShoot?


lemming - Di 30.07.02 12:59

Mit


Quelltext
1:
2:
3:
  bm.Canvas.CopyRect(sr,cnv,sr);
  km.Canvas.StretchDraw(kr, bm);
  km.savetofile(datei);


Mit ersten Zeile wird der Screenshot gemacht, mit den zwei unteren gestreched und abgespeichert. Naja, je nach Auflösung und Desktopgröße kann das ein wenig dauern und somit zu rucklern führen.


wwerner - Di 30.07.02 13:02

Versuch mal das:


Quelltext
1:
2:
3:
4:
5:
bm.Canvas.CopyRect(sr,cnv,sr); 
Application.processmessages
km.Canvas.StretchDraw(kr, bm); 
Application.processmessages
km.savetofile(datei);


Aber was ruckelt?


hitstec - Di 30.07.02 21:17

Oder versuchs mit einem neuen Thread --- näher will ich da nicht eingehen, steht alles in der Hilfe.

Weiß eigentlich jemand wie man resourcensparend, schnell und sicher einen kompletten Scrennshot macht?


Arakis - Di 30.07.02 21:32

Hi,
hab ein Beispiel im EDH gefunden, aber auch nicht viel schneller:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
procedure ScreenCapture(Bmp: TBitmap);
var
  DeskWnd: HWnd;
  DeskDC: HDC;
  DeskCv: TCanvas;
  R: TRect;
  W, H: Integer;
begin
  if Bmp = nil then Exit;
  DeskWnd := GetDesktopWindow;
  DeskDC := GetWindowDC(DeskWnd);
  DeskCv := TCanvas.Create;
  DeskCv.Handle := DeskDC;
  W := Screen.Width;
  H := Screen.Height;
  R := Bounds(0, 0, W, H);
  try
    Bmp.HandleType := bmDIB;
    Bmp.PixelFormat := pf24Bit;
    Bmp.Width := W;
    Bmp.Height := H;
    Bmp.Canvas.CopyMode := cmSrcCopy;
    Bmp.Canvas.CopyRect(R, DeskCv, R);
  finally
    DeskCv.Free;
    ReleaseDC(DeskWnd, DeskDC);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
self.Image1.Picture.Bitmap:=TBitmap.Create;
ScreenCapture(self.Image1.Picture.Bitmap);
end;


Bis dann
user defined image


hitstec - Di 30.07.02 21:38

Ja, danke.

Die ist nich schlecht .. kenn ich aber schon .. :wink:

Es gibt doch Programme die einen Screen-Capture machen und es dann als AVI sichern -> Überwachungsprogramme.
Weiß jemand darüber Bescheid.


Arakis - Di 30.07.02 21:44

NaNa, das ist aber nicht die feine Art. Ich kenn auch ein Programm, dass speichert den gesamten Soundstream, der an die Soundkarte geht, auf Festplatte ab :mrgreen:
Dein Programm gibt es bestimmt irgendwo im Internet, nimm einfach mal google.

Bis dann
user defined image


hitstec - Di 30.07.02 21:49

Du hast mich falsch verstanden, ich würde gern wissen wie die Technik genau funktioniert.

Die Programme ansich habe ich schon gesehen und benutzt.

Kennt jemand PC-Anywhere? Das schickt ganze Screenshots per Internet und der Empgänger sieht sie teilweise in Echtzeit. Weiß jemand wie das funkt?


Arakis - Di 30.07.02 21:55

Jo, kenn ich. Und VNC. Beide Programme fangen die Windows-Messages ab, die das zeichnen von Komponenten veranlassen. Dabei wird dann von der neu zu zeichnenden Komponente ein Mini-Screenshot gemacht. Das Thema hatten wir mal im alten DF und kamen zum Entschuss, dass da verdammt viel technik hintersitzt, um das einigermaßen schnell hinzubekommen.

Bis dann
user defined image


Maverick - So 04.08.02 23:49

am schnellsten den Screenshot machen kann man mit der WindowsAPI

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.Button1Click(Sender: TObject);
var bmpCapture:TBITMAP;
    DesktopDC:CARDINAL;
begin
  DesktopDC:=getWindowDC(0); //0 ist das Handle des SCREEN
  bmpCapture:=TBitmap.Create;
  bmpCapture.Width:=screen.Width;
  bmpCapture.Height:=screen.Height;
  bmpCapture.PixelFormat:=pf32bit;
  Bitblt(bmpCapture.canvas.handle,0,0,screen.width,screen.height,DesktopDC,0,0,SRCCOPY);
  form1.Canvas.Draw(0,0,bmpCapture);
end;

wobei alles bis auf(bmpCapture.canvas.handle,0,0,screen.width,screen.height,DesktopDC,0,0,SRCCOPY);
am anfang und ende des Programms gemacht werden kann.

Um die daten in echtzeit über das netz zu übertragen, ist neben dem MessageHook für WM_PAINT auch noch einiges andere notwendig:
ein schneller, aber effektiver kompressionsalgorithmus (für den anfang RLE)
ein sparsames windows mit wenig grafik, damit die kompression auch funcitoniert (win 98 ohne Themes, Fensteranimationen und Hintergründe, kein verlauf in der Titelleiste)
am besten ne Datenreduktion (8bit Graustufen ist eigentlich echt gut, vielleicht sind auch 5bit oder weniger noch okay)