AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Screenshot machen (zum 125.000sten Mal *gg*)

Screenshot machen (zum 125.000sten Mal *gg*)

Ein Thema von Codehunter · begonnen am 9. Aug 2012 · letzter Beitrag vom 13. Aug 2012
Antwort Antwort
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.291 Beiträge
 
Delphi 12 Athens
 
#1

AW: Screenshot machen (zum 125.000sten Mal *gg*)

  Alt 13. Aug 2012, 09:43
So, inzwischen ist doch noch ein Problemchen aufgetaucht: Ich habe mich als gewohnheitsmäßiger Multimonitor-User an das MSDN gehalten. Zitat:
Zitat:
If there are multiple monitors on the system, calling CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL) will create a DC covering all the monitors.
Und was ist? Nischt ist! Platziert man ein Fenster über der Schnittlinie zweier Monitore, dann grabbt die Routine nur den Teil des Fensters, der auf dem primären Bildschirm liegt. Der Teil außerhalb wird zwar von den Dimensionen des Bitmaps her richtig erfasst, ist aber schön weiß eingefärbt.

Liegt das Fenster gänzlich auf einem sekundären Bildschirm, dann ist der Screenshot komplett weiß.

Hat jemand eine Idee woran das nun wieder liegt?

EDIT: *Kopfklatsch* - Das war mal wieder ein zu niedriger Kaffeepegel *gg* Ich habe mit GetDeviceCaps die Auflösung geholt und da scheints etwas inkonsequent zu werden beim Win32API. Zwar habe ich den DC für den kompletten Desktop über alle Bildschirme richtig geholt, aber GetDeviceCaps liefert trotzdem nur den primären Monitor:
Zitat:
On a multiple monitor system, if hdc is the desktop, then GetDeviceCaps returns the capabilities of the primary monitor.
Also habe ich stattdessen Screen.DesktopHeight bzw. Screen.DesktopWidth verwendet und schon gehts.
Angehängte Grafiken
Dateityp: png Image2.png (36,5 KB, 24x aufgerufen)

Geändert von Codehunter (13. Aug 2012 um 09:53 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.689 Beiträge
 
Delphi 2007 Enterprise
 
#2

AW: Screenshot machen (zum 125.000sten Mal *gg*)

  Alt 13. Aug 2012, 09:51
Zitat:
If lpszDriver is DISPLAY or the device name of a specific display device, then lpszDevice must be NULL or that same device name. If lpszDevice is NULL, then a DC is created for the primary display device.

If there are multiple monitors on the system, calling CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL) will create a DC covering all the monitors.
Das ist wiedersprüchlich im MSDN. Im oberen Teil steht quasi:
CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL) --> DC für primären Bildschirm
CreateDC(TEXT("DISPLAY"),TEXT("DISPLAY"),NULL,NULL ) --> DC für alle Bildschirme

Während im unteren deine Interpetation steht:
CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL) --> DC für alle Bildschirme

Probier mal mit 2x 'DISPLAY', vielleicht war es das ja schon. (Wie ich solche Finten in Dokus liebe...)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.291 Beiträge
 
Delphi 12 Athens
 
#3

AW: Screenshot machen (zum 125.000sten Mal *gg*)

  Alt 13. Aug 2012, 09:56
Hat sich zwischenzeitlich erledigt. Siehe EDIT im Post vorher. Bei solchen Gelegenheiten merkt man dann wieder, dass der Multimonitor-Betrieb nicht zum ursprünglichen Design von Windows gehörte sondern bei Win98 quasi "drangeflanscht" wurde.

Richtig eklig wird es immer dann, wenn Bildschirmkoordinaten plötzlich negativ werden weil ein Monitor logisch gesehen links vom primären Bildschirm liegt.
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.291 Beiträge
 
Delphi 12 Athens
 
#4

AW: Screenshot machen (zum 125.000sten Mal *gg*)

  Alt 13. Aug 2012, 11:28
So, das sollte sie nun sein, die Screenshotfunktion die unter allen erdenklichen Multimonitor-Geometrien funktioniert. Man sollte aber bedenken, dass CreateDC('DISPLAY' laut MSDN erst ab Windows 2000 funktioniert.
Delphi-Quellcode:
procedure CaptureScreen(ABitmap: Graphics.TBitmap);
const
   CAPTUREBLT = $40000000;
var
   hdcScreen: HDC;
   hdcCompatible: HDC;
   hbmScreen: HBITMAP;
   DeskHeight, DeskWidth, LeftOffset, TopOffset: Integer;
begin
  hdcScreen:= CreateDC('DISPLAY', NIL, NIL, NIL);
  hdcCompatible:= CreateCompatibleDC(hdcScreen);
  DeskHeight:= Screen.DesktopHeight;
  DeskWidth:= Screen.DesktopWidth;
  LeftOffset:= Screen.DesktopLeft;
  TopOffset:= Screen.DesktopTop;

  hbmScreen:= CreateCompatibleBitmap(hdcScreen,
                                     DeskWidth,
                                     DeskHeight);

  SelectObject(hdcCompatible, hbmScreen);
  ABitmap.Handle:= hbmScreen;
  BitBlt(hdcCompatible, 0, 0, ABitmap.Width, ABitmap.Height, hdcScreen,
         LeftOffset, TopOffset, SRCCOPY or CAPTUREBLT);

  DeleteDC(hdcScreen);
  DeleteDC(hdcCompatible);
end;

procedure GrabScreenshotFromWindow(AHandle: HWND;
  ATargetBitmap: Graphics.TBitmap);
var
  R: TRect;
  DeskBMP: Graphics.TBitmap;
  WinHeight, WinWidth, LeftOffset, TopOffset: Integer;
begin
  DeskBMP:= Graphics.TBitmap.Create;
  R:= Screen.DesktopRect;
  LeftOffset:= Abs(R.Left);
  TopOffset:= Abs(R.Top);
  try
    CaptureScreen(DeskBMP);
    GetWindowRect(AHandle, R);
    Inc(R.Left, LeftOffset);
    Inc(R.Top, TopOffset);
    Inc(R.Right, LeftOffset);
    Inc(R.Bottom, TopOffset);
    WinHeight:= R.Bottom - R.Top;
    WinWidth:= R.Right - R.Left;
    ATargetBitmap.Width:= WinWidth;
    ATargetBitmap.Height:= WinHeight;
    ATargetBitmap.Canvas.CopyRect(Rect(0, 0, WinWidth, WinHeight), DeskBMP.Canvas, R);
  finally
    DeskBMP.Free;
  end;
end;
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz