| Autor |
Beitrag |
Boldar
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Sa 26.06.10 00:09
Hallo,
ich habe mal wieder ein Problem:
ich möchte unter Win7 x64 einen Screenshot eines speziellen Fensters erstellen und auf die Platte schmeissen.
Ich habe schon Das hier aus der library sowie das hier aus der DP und das hier von Assarbad probiert.
Nichts geht. Bei Assarbads Version kriege ich keine Datei, obwohl das Handle gültig ist, bei den anderen ist die Datei leer, also 0 byte groß, aber immerhin vorhanden.
Das kann doch nicht so schwer sein. Ich suche einfach eine Möglichkeit, alle 18ms einen Screenshot eines Fensters zu speichern.
mfg Boldar
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Sa 26.06.10 03:15
schon mal probiert sich das bild direkt in delphi anzeigen zu lassen um zu sehen ob der code zumindestens was macht?
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
jaenicke
      
Beiträge: 19340
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 26.06.10 06:59
Zwei gängige Probleme wären:
1. Der Zielprozess wurde mit Adminrechten gestartet. Es kann sein, dass das dann nicht klappt, da dann die Kommunikation eingeschränkt ist, wenn der eigene Prozess keine hat.
2. Es handelt sich um ein DirectX- oder OpenGL-Fenster. In diesem Fall geht es nicht so einfach.
Hast du einmal versucht von einem anderen Fenster mit dem selben Code einen Screenshot zu machen? Um den Code an sich zu testen meine ich.
|
|
Boldar 
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Sa 26.06.10 13:57
Ich habe als Fenster testweise Notepad genommen, das ist wohl kaum dirctx, das Handle ist gültig und meine IDE wird mit Adminrechten gestartet, also erben die Programme diese doch?
Ich werde das mit dem Anzeigen lassen gleich mal probieren.
|
|
jaenicke
      
Beiträge: 19340
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 26.06.10 15:03
Dann zeig doch einfach mal deinen Code, in dem du das Fenster von Notepad findest.
Denn den Code hier aus der Library hatte ich selbst schonmal mit Notepad ausprobiert soweit ich mich erinnere. Ich werde es heute Abend noch einmal testen, wenn ich vorn der Arbeit komme (hab Pause  ).
|
|
Boldar 
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Sa 26.06.10 15:20
Ich habe momentan folgenden Code:
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: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82:
| program gamestream;
{$APPTYPE CONSOLE}
uses SysUtils, windows, classes, graphics, tlhelp32, dialogs;
var WIndowhandle:THandle;
function FormularSaveScreenShot(FileName: String; h : hWnd): Boolean; var Rec: TRect; iWidth, iHeight: Integer; begin with TBitmap.Create do try GetWindowRect(h, Rec);
iWidth := Rec.Right - Rec.Left;
iHeight := Rec.Bottom - Rec.Top; Width := iWidth; Height := iHeight; BitBlt(Canvas.Handle, 0, 0, iWidth, iHeight, GetWindowDC(h), 0, 0, SRCCOPY); Result := True; try SaveToFile(Filename) except Result := False end; finally ReleaseDC(h, GetWindowDC(h)); Free; end; end;
function MyEnumWindowProc(AHandle: THandle; LParam: LongWord): boolean; stdcall; var ProcessID: THandle; begin ProcessID := 0; GetWindowThreadProcessID(AHandle, ProcessID); Result := not (ProcessID = LParam); if not Result then WindowHandle := AHandle; end;
function GetWindowHandleByExeName(const AExeName: string): THandle; var SnapShot: THandle; p: TProcessEntry32; ProcessHandle: THandle; begin Result := 0; WindowHandle := 0; ProcessHandle := 0; p.dwSize := SizeOf(p); SnapShot := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0); try if Process32First(SnapShot, p) then repeat if AnsiLowerCase(AExeName) = AnsiLowerCase(p.szExeFile) then ProcessHandle := p.th32ProcessID; until (ProcessHandle <> 0) or not Process32Next(SnapShot, p); EnumWindows(@MyEnumWindowProc, ProcessHandle); Result := WindowHandle; finally CloseHandle(SnapShot); end; end;
var H: THandle; var bmp: TBitmap;
begin h:=Getwindowhandlebyexename('notepad.exe'); sleep(1000); if formularsavescreenshot ('C:\img.bmp', h) then showmessage ('succes'); readln; end. |
|
|
Dude566
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: Sa 26.06.10 15:31
Ich habe mir das Programm von jaenicke schon länger nicht mehr angesehen, aber vielleicht findest du darin ja Hilfe.
www.delphi-forum.de/...5+alpha+3_96542.html
_________________ Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Sa 26.06.10 15:35
Folgendes zu diesem Befehl:
Delphi-Quelltext 1:
| CreateToolhelp32Snapshot |
| MSDN hat folgendes geschrieben: |
If the specified process is a 64-bit process and the caller is a 32-bit process, this function fails and the last error code is ERROR_PARTIAL_COPY (299).
|
Ich denke das könnte der Grund sein??? Hast du eigentlich GetLastError() mal aufgerufen?
lg elundril
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
Boldar 
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Sa 26.06.10 17:29
Das handle ist gültig, ich habe es auch schon mit einem 32-bit-Process probiert, und getlasterror ist null.
Und formularsavescreenshot gibt true zurück. Alles irgendwie sehr komisch.
--- Moderiert von Narses: Beiträge zusammengefasst---
Also, folgendes geht:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure MakeScreenShot(const ATarget: TBitmap); var DesktopDC: HDC; begin DesktopDC := CreateDC('DISPLAY', nil, nil, nil); try ATarget.PixelFormat := pfDevice; ATarget.Width := 1280; ATarget.Height := 1024; BitBlt(ATarget.Canvas.Handle, 0, 0, 1280, 1024, DesktopDC, 0, 0, SRCCOPY); finally DeleteDC(DesktopDC); end; end; |
und gibt ein screenshot des Desktops zurück.
Folgendes:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| function FormularSaveScreenShot(FileName: String; h : hWnd): Boolean; var Rec: TRect; iWidth, iHeight: Integer; begin result:=false; with TBitmap.Create do try GetWindowRect(h, Rec);
iWidth := Rec.Right - Rec.Left; iHeight := Rec.Bottom - Rec.Top; Width := iWidth; Height := iHeight; BitBlt(Canvas.Handle, 0, 0, iWidth, iHeight, GetWindowDC(h), 0, 0, SRCCOPY); Result := True; try SaveToFile(Filename) except Result := False end; finally ReleaseDC(h, GetWindowDC(h));
Free; end; end; |
geht nicht und gibt ein leeres Bitmap zurück. Selbst mit admin-rechten. Wenn ich allerdings als h das Handle des eigenen Fensters übergebe, funktioniert das einwandfrei.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 26.06.10 20:02
Klasse Fehlerbehandlung: Result := True;.  Woher weißt du, dass alle vorherigen Funktionsaufrufe fehlerfrei waren?
| Zitat: | | Selbst mit admin-rechten. Wenn ich allerdings als h das Handle des eigenen Fensters übergebe, funktioniert das einwandfrei. |
Lass doch mal das rumngewurstel mit den unterschiedlichen Benutzerkonten und starte dein Programm und das Programm, von dem du den Screenshot haben willst im gleichen Kontext.
|
|
Boldar 
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Sa 26.06.10 20:06
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 26.06.10 21:33
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Sa 26.06.10 21:39
Ich zitiere mich ja nur ungern aber:
elundril hat folgendes geschrieben : |
Hast du eigentlich GetLastError() mal aufgerufen?
lg elundril |
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
jaenicke
      
Beiträge: 19340
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 26.06.10 22:54
Das wird damit gar nix zu tun haben. Das gefundene Fenster ist einfach irgendein Fenster vom Editor. Das muss aber nicht das sichtbare sein...
Wie wäre es, wenn du in deiner Callback-Prozedur schaust, ob das Fenster zumindest sichtbar ist?
(Ob es das ist was du willst, ist nochmal ne andere Frage, hab grad keine Lust zu testen.)
So in der Art meine ich in MyEnumWindowProc: Delphi-Quelltext 1:
| Result := not ((ProcessID = LParam) and IsWindowVisible(AHandle)); |
Für diesen Beitrag haben gedankt: Boldar
|
|
|