Autor Beitrag
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 26.06.10 15:03 
Dann zeig doch einfach mal deinen Code, in dem du das Fenster von Notepad findest. :gruebel:

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 :D).
Boldar Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Sa 26.06.10 15:20 
Ich habe momentan folgenden Code:
ausblenden volle Höhe Delphi-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:
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, 00, iWidth, iHeight, GetWindowDC(h), 00, 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 <> 0or not Process32Next(SnapShot, p);
    EnumWindows(@MyEnumWindowProc, ProcessHandle);
    Result := WindowHandle;
    finally
    CloseHandle(SnapShot);
    end;
end;

var H: THandle;
var bmp: TBitmap;

begin
  { TODO -oUser -cConsole Main : Hier Code einfügen }
  h:=Getwindowhandlebyexename('notepad.exe');
  sleep(1000);
  if formularsavescreenshot ('C:\img.bmp', h) then showmessage ('succes');
  readln;
end.
Dude566
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: Sa 26.06.10 15:31 
Ich habe mir das Programm von user profile iconjaenicke 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Sa 26.06.10 15:35 
Folgendes zu diesem Befehl:

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: 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 user profile iconNarses: Beiträge zusammengefasst---

Also, folgendes geht:
ausblenden 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'nilnilnil);
  try
    ATarget.PixelFormat := pfDevice;
    ATarget.Width := 1280;
    ATarget.Height := 1024;
 
    BitBlt(ATarget.Canvas.Handle, 0012801024, DesktopDC, 00, SRCCOPY);
  finally
    DeleteDC(DesktopDC);
  end;
end;

und gibt ein screenshot des Desktops zurück.
Folgendes:
ausblenden 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, 00, iWidth, iHeight, GetWindowDC(h), 00, 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



BeitragVerfasst: Sa 26.06.10 20:02 
Klasse Fehlerbehandlung:Result := True;. :roll: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Sa 26.06.10 20:06 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Klasse Fehlerbehandlung:Result := True;. :roll: Woher weißt du, dass alle vorherigen Funktionsaufrufe fehlerfrei waren?

Ist ja nicht von mir, aber wenns ne exception gibt, kommt er ja nie dahin.
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:

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.

Ich habe sowohl beide als Admin, als auch beide als normaler User, als auch verschiedene gemischte Varianten probiert.
Naja, wenns so nicht geht, mache ich halt nen screenshot und schneide das dann raus.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 26.06.10 21:33 
user profile iconBoldar hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Klasse Fehlerbehandlung:Result := True;. :roll: Woher weißt du, dass alle vorherigen Funktionsaufrufe fehlerfrei waren?

Ist ja nicht von mir, aber wenns ne exception gibt, kommt er ja nie dahin.

API-Funktionen werfen keine Exception.
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Sa 26.06.10 21:39 
Ich zitiere mich ja nur ungern aber:

user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
  Result := not ((ProcessID = LParam) and IsWindowVisible(AHandle));					

Für diesen Beitrag haben gedankt: Boldar