![]() |
ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Hallo,
mittels folgenden Code mache ich von einem aktiven Fenster einen ScreenShot:
Delphi-Quellcode:
Dummerweise hab ich eine Software (nicht von mir, ist vom Siemens) dessen Inhalt der Form
procedure ScreenShot_aktives_Fenster(Bild: TBitMap);
var c: TCanvas; r, t: TRect; h: THandle; begin c := TCanvas.Create; c.Handle := GetWindowDC(GetDesktopWindow); h := GetForeGroundWindow; If h <> 0 then GetWindowRect(h, t); try r := Rect(0, 0, t.Right - t.Left, t.Bottom - t.Top); Bild.Width := t.Right - t.Left; Bild.Height := t.Bottom - t.Top; Bild.Canvas.CopyRect(r, c, t); finally ReleaseDC(0, c.Handle); FreeAndNil(c); end; end; zu groß für das maximierte Fenster ist, so dass die Scrollbars angezeigt werden. Wie könnt ich nun einen Screenshot des kompletten (großen) Inhalts des Fensters machen? |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Ich meine, dass ich vor einiger Zeit das gleiche Problem hatte. Versuche es doch mal mit diesem Code.
Delphi-Quellcode:
procedure ScreenShot(wnd: HWND; destBitmap : TBitmap) ; var w,h : integer; DC : HDC; r : TRect; DCProgr : HDC; begin SetActiveWindow(wnd); DCProgr:=GetForegroundWindow; if DCProgr <> wnd then begin SetForegroundWindow(wnd); sleep(Delay4ScreenShot); end; dc := GetWindowDC(wnd) ; GetWindowRect(wnd,r) ; w := r.Right - r.Left; h := r.Bottom - r.Top; try destBitmap.Width := w; destBitmap.Height := h; BitBlt(destBitmap.Canvas.Handle, 0, 0, destBitmap.Width, destBitmap.Height, DC, 0, 0, SRCCOPY) ; finally ReleaseDC(wnd, DC) ; end; SetForegroundWindow(DCProgr); end; |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Danke für den Code!
Nur leider wird da auch nur das sichtbare vom Fenster abfotographiert |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Zitat:
Ich habe noch eine weitere Funktion gefunden, hatte dann aber drübergeschrieben, dass diese nur unter XP und Vista geht. Kannst ja nochmal probieren.
Delphi-Quellcode:
//geht nur mit Win XP oder Vista, jedenfalls Funktion "PRINTWINDOW" function ScreenshotHidden(wnd: HWND; const bmp: TBitmap): Boolean; var rec: TRect; //zum Zwischenspeichern der Fenstergröße dllh: THandle; //Handle der user32.dll PrintWindow: function(sHandle: HWND; dHandle: HDC; nFlags: UINT): BOOL; stdcall; //Prototyp der verwendeten Funktion begin Result := False; //Rückgabewert initialisieren dllh := GetModuleHandle(user32); //dll dynamisch laden... if dllh <> 0 then begin @PrintWindow:= GetProcAddress(dllh , 'PrintWindow'); //die Funktionsadresse aus der Dll laden... if @PrintWindow = nil then begin ShowMessage('@PrintWindow = nil'); end else begin GetWindowRect(wnd, rec); //Größe des Fensters auslesen... ShowMessage(Format('left "%d", right "%d", top "%d", bottom "%d"',[rec.Left, rec.Right, rec.Top, rec.Bottom])); bmp.Width := rec.Right - rec.Left; //...und die Bitmap-Größe anpassen bmp.Height := rec.Bottom - rec.Top; bmp.Canvas.Lock; //Zugriff auf den Canvas für andere Threads blockieren try result := PrintWindow(wnd, bmp.Canvas.Handle, 0); //Das Fenster zeichnet sich selbst in das HDC des Bitmaps finally bmp.Canvas.Unlock; //Zugriff wieder erlauben end; end; end; end; |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
also entweder mach ich was falsch oder es geht nicht
Mit diesem Code mach ich ein Foto:
Delphi-Quellcode:
Ich nutz meine Procedure um jetzt nicht im Code überall ändern zu müssen und ausserdem wird dort
function ScreenshotHidden(wnd: HWND; const bmp: TBitmap): Boolean;
var rec: TRect; //zum Zwischenspeichern der Fenstergröße dllh: THandle; //Handle der user32.dll PrintWindow: function(sHandle: HWND; dHandle: HDC; nFlags: UINT): BOOL; stdcall; //Prototyp der verwendeten Funktion begin Result := False; //Rückgabewert initialisieren dllh := GetModuleHandle(user32); //dll dynamisch laden... if dllh <> 0 then begin @PrintWindow:= GetProcAddress(dllh , 'PrintWindow'); //die Funktionsadresse aus der Dll laden... if @PrintWindow = nil then begin ShowMessage('@PrintWindow = nil'); end else begin GetWindowRect(wnd, rec); //Größe des Fensters auslesen... ShowMessage(Format('left "%d", right "%d", top "%d", bottom "%d"',[rec.Left, rec.Right, rec.Top, rec.Bottom])); bmp.Width := rec.Right - rec.Left; //...und die Bitmap-Größe anpassen bmp.Height := rec.Bottom - rec.Top; bmp.Canvas.Lock; //Zugriff auf den Canvas für andere Threads blockieren try result := PrintWindow(wnd, bmp.Canvas.Handle, 0); //Das Fenster zeichnet sich selbst in das HDC des Bitmaps finally bmp.Canvas.Unlock; //Zugriff wieder erlauben end; end; end; end; procedure ScreenShot_aktives_Fenster(Bild: TBitMap); var c: TCanvas; r, t: TRect; h: THandle; begin c := TCanvas.Create; c.Handle := GetWindowDC(GetDesktopWindow); h := GetForeGroundWindow; If h <> 0 then ScreenshotHidden(h, Bild); end; das Handle des Fensters ausgelesen (ich hoffe das ist das richtige für die function). Leider wird trotzdem nur der sichtbare Teil bildlich dargestellt |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Sorry, mehr Code habe ich in dem Programm nicht gefunden.
Kann es sein, dass dies erst verfügbar ist, wenn man es auf dem Bildschirm sieht? |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Zitat:
also keine Hintergrund-Bildermacherei |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Ich habe diesen
![]() Wenn ich den so aufrufe, dann erhalt ich nur ein schwarzes Bitmap:
Delphi-Quellcode:
Ist mein Aufruf falsch?
procedure PrintWindow(Wnd: HWND; ATo: TBitmap);
var hDCMem : HDC; DC : HDC; rect : TRect; bmp : HBITMAP; hOld : HGDIOBJ; begin hDCMem:=CreateCompatibleDC(0); GetWindowRect(Wnd, rect); bmp:=0; DC:= GetDC(Wnd); bmp:= CreateCompatibleBitmap(DC, rect.Right-rect.Left, rect.Bottom-rect.Top); ReleaseDC(Wnd, DC); hOld:=SelectObject(hDCMem, bmp); SendMessage(wnd, wm_Print, hDCMem, PRF_CHILDREN or PRF_CLIENT or PRF_ERASEBKGND or PRF_NONCLIENT or PRF_OWNED); selectObject(hDCMem, hold); DeleteObject(hDCMem); ATo.FreeImage; ATo.Handle:=bmp; end; procedure ScreenShot_aktives_Fenster(Bild: TBitMap); var h: THandle; begin h := GetForeGroundWindow; If h <> 0 then PrintWindow(h, Bild); end; |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Wie sieht das Ergebnis aus wenn du PRF_ERASEBKGND aus dem SendMessage-Aufruf entfernst?
|
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Zitat:
Die Lösung besteht darin, zwei Bildschirmfotos zu machen und die dann zusammenzufügen. Das kann man, wenn man das häufiger benötigt, natürlich automatisieren, will sagen: von einer Software erledigen lassen. |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Zitat:
Zitat:
Zitat:
Leider ist das Fenster so groß, dass ich nicht nur horizontal sondern auch vertikal scrollen müsste und dann die Bilder dementsprechend zusammensetzen muss |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Ich habe das mal so gemacht (vor Jahren), finde das aber leider nicht mehr.
Es wurde halt eine große bmp erstellt. |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Zitat:
könntest du auf dem Dachboden (oder Keller) nach dem Code suchen? :-) |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Ich hatte doch noch einen Tresor im Garten vergraben, den musste ich nur noch ausbuddeln und aufschweißen... ;-)
Musst Du mal schauen, ob Dich das auf den Weg bringen kann: - DesignerBoxTournament ist eine Scrollbox - Designer ist ein Panel in der Scrollbox, das den Kontent enthält (und der Gesamtgröße entspricht) - ImageCopy ist ein TImage
Delphi-Quellcode:
procedure TFormTurniere.sButtonCopyClick(Sender: TObject);
var DR, SR: TRect; X, Y: Integer; begin Beep; ImageCopy.Picture.Bitmap.Width := DesignerBoxTournament.Designer.Width; ImageCopy.Picture.Bitmap.Height := DesignerBoxTournament.Designer.Height; DR.Left := 0; DR.Top := 0; DR.Right := ImageCopy.Picture.Bitmap.Width; DR.Bottom := ImageCopy.Picture.Bitmap.Height; ImageCopy.Canvas.FillRect(DR); Y := 0; while Y < DesignerBoxTournament.Designer.Height do begin X := 0; while X < DesignerBoxTournament.Designer.Width do begin DesignerBoxTournament.HorzScrollBar.Position := X; DesignerBoxTournament.VertScrollBar.Position := Y; //ShowDummy(DesignerBoxTournament); // ... baute den Inhalt auf Application.ProcessMessages; Sleep(500); DR.Left := X; DR.Top := Y; DR.Right := X + DesignerBoxTournament.ClientWidth; DR.Bottom := Y + DesignerBoxTournament.ClientHeight; SR.Left := X; SR.Top := Y; SR.Right := X + DesignerBoxTournament.ClientWidth; SR.Bottom := Y + DesignerBoxTournament.ClientHeight; ImageCopy.Canvas.CopyRect(DR, DesignerBoxTournament.Designer.Canvas, SR); Inc(X, DesignerBoxTournament.ClientWidth); end; Inc(Y, DesignerBoxTournament.ClientHeight); end; ImageCopy.Picture.Bitmap.SaveToFile(Path + 'Copy.bmp'); end; |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Zitat:
Zitat:
bzw. auf mein Problem anzuwenden. |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Muss man zu dieser Zeile noch etwas wissen?
Delphi-Quellcode:
Ein Panel (Designer) hat doch kein Canvas oder hab ich was übersehen?
ImageCopy.Canvas.CopyRect(DR, DesignerBoxTournament.Designer.Canvas, SR);
|
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Den Canvas hatte ich (glaube ich) extra veröffentlicht.
Du müsstest evtl. auch den Canvas der Scrollbox oder des Formulars nehmen können. Genauer kann ich das schlecht nachvollziehen weil meine Aktivitäten dazu schon länger her sind. |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Im Grunde genommen hab ich deinen Code verstanden.
Wenn ich das nun auf mein eigentliches Problem ummünze dann hab ich aber ein anderes Problem. Dein Code weiss von Anfang an, wie groß das Ursprüngliche ist und scrollt dann über X und Y an die Endposition hin. Wenn ich aber einen ScreenShot des fremden Fensters machen will, weiss ich nicht, wie groß das Gesamte ist. Ich müsste also wissen, wie weit ich scrollen muss. - Ich finde aber nichts um rauszufinden, ob die Scrollbalken angezeigt werden, oder wie weit ich scrollen muss. Wenn ich das wüsste, dann könnt ich deinen Code darauf anwenden. |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
zwei Möglichkeiten:
1) Scrolle einfach immer weiter und teste, wie weit Position tatsächlich verschoben wurde. Die Differnz zur letzten Position ist dann der neue Bereich. 2) Schau Dir mal die Eigenschaften der Scrollbars an. Die wissen auf jeden Fall, wie groß die Bereiche in X- und Y-Richtung sind (irgendwas miz Range oder so). |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
mmh - aber wie bekomm ich die Position raus?
Ich bin ja in einem fremden Fenster |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Ich meinte die MyScrollBox.HorzScrollBar.Position...
Wenn die z.B. 100 war und Du 50 hinzuadierst, ist sie vielleicht tatsächlich bei 120 (weil es die maximale Scrollweite ist). Der bessere Weg wäre aber sicher, die maximale Weite vorab aus der ScrollBar zu ermitteln. Musst Du mal ein bischen damit herum spielen. |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Stahli, ich glaube wir reden aneinander vorbei (oder ich versteh dich nicht)
ich hab ein fremdes Fenster (also nicht von meinem Programm) dessen Inhalt zu groß ist und gescrollt gescreenshotet werden soll. Deswegen müsst ich ja das fremde Fenster scrollen und wissen wie weit ich gescrollt hab. |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Zitat:
Also überleg's dir: Bevor du hier versuchst, unlösbare Aufgaben zu lösen und deine wertvolle Zeit damit verplemperst, gibst du besser ein wenig Geld aus und hast dabei noch etliche weitere Vorteile erzielt. |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Ich gib dir ja recht...
Nur, erstens hab ich das Problem in der Firma. Dann nur bei einer Software vom Siemens, die den Inhalt des Fensters nicht an das Fenster angleichen (können), sondern auf dem Original lassen |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Ah, ok, das hatte ich nicht verstanden.
Dann könnte ich auch nur einen 30''er (2560*1600) empfehlen. ;-) |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Zitat:
|
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Ansonsten hätt ich noch folgende Idee:
Den Parent des fremden Fensters auf ein Panel in meiner SW zu setzen und dann Stahlis Code drauf ansetzen ned schee... was hälst ihr davon? |
AW: ScreenShot eines Fensters machen dessen Inhalt größer Formgröße ist
Liste der Anhänge anzeigen (Anzahl: 1)
Also ich hab da jetzt mal was zusammengeschustert
(vorab schonmal: es ist nur eine Testvariante - daher sehr schlampig) Mittels Alt+F1 wird das Vordergund-Fenster in das Panel geholt Mittels dem Button wird dann ein Foto gemacht (mit Stahlis Code) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:41 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