![]() |
Durchsichtiges Fenster (nicht Alpha Blend)
Ich arbeite an einem Grafikprogramm, und möchte gern eine Form als Rahmen für einen Screenshot benutzen.
Dafür sollte allerdings die Form, also die Oberfläche durchsichtig sein. Die Titelleiste und die Umrandung allerdings nicht! Das soll ja als Rahmen dienen. Und da ich mir da noch keine Gedanken drüber gemacht habe: Gibt es einen Befehl, zum Screenshot machen? Danke schonmal! |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
ich weiß nicht, wies mit vorherigen versionen is, aber bei delphi6 gibts die eigenschaften TransparentColor und TransparentColorValue! die könnteste dir mal anschaun!
screenshot dürfteste hier in der forumsuche leicht finden! |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Liste der Anhänge anzeigen (Anzahl: 1)
Das Beispiel zum ausschneiden:
![]() Und ein altes Demo von mir um eine andere Form zu erstellen Ein Vorschlag: ein Rechteck erstellen und aus diesem ein kleineres Rechteck ausschneiden (rdn_diff). Da das in dem Beispiel auf Images angewendet wird, musst du nur
Delphi-Quellcode:
durch
SelectObject(XXX.Canvas.Handle, RHandle);
Delphi-Quellcode:
ersetzen.
SetWindowRgn(Form1.Handle, RHandle, True);
|
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Danke, ich habe schon eine gute Methode gefunden:
Ich benutze "TransparentColor". Jetzt ist nurnoch das Problem mit dem Screenshot. Ich habe mir die anderen Beiträge schon angesehen, aber bei keinem war das richtige dabei... Ich habe also bsw. auf einer anderen minimierten Form ein TImage. Die Größe davon wird gleichgesetzt mit der Formgröße. Jetzt soll genau der Bereich der Form(die mit TransparentColor) in des TImage kopiert werden. Danke! [Edit:]PS: Ich habe mir die beiden Programme mal angesehen. Das eine war toll, das andere erstaunlich. Aber ich bin sozusagen Anfänger bzw. ich bringe mir alles selbst bei und lerne durch Versuchen... Handles und Messages sind immernoch ein Rätsel für mich. :wall: Zum Glück gibts dieses super Forum! :thuimb: |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Da fällt mir auf Anhieb diese kleine Taste ein - DRUCK, PRINT oder wie die noch so heißt.
Dadurch wird eine Kopie des Bildschirms in die Zwischenablage gelegt. Diese kann man mit LoadFromClipboardFormat ins Image holen. Dann muss das Bild nur noch an Hand der Fensterposition und -grösse beschitten werden.
Delphi-Quellcode:
Es gibt dann noch die Möglichkeit die Windowsbotschaften abzuhören oder mit einem Timer zu prüfen, ob sich die Zwischenablage geändert hat. Wenn ein BitMap mit der Grösse und Farbauflösung des Monitors im Zwischenspeicher ist, ist die Chance groß, das es ein Screenshot ist.
Uses ClipBrd;
Procedure TForm1.Button1Click(Sender: TObject); Var BitMap : TBitMap; RahmenbreiteX, RahmenbreiteY: Integer; Begin BitMap := TBitMap.Create; Try BitMap.LoadFromClipBoardFormat(cf_BitMap, ClipBoard.GetAsHandle(cf_Bitmap), 0); Image1.Picture.BitMap.Width := Breite des Ausschnitts; Image1.Picture.BitMap.Height := Höhe des Ausschnitts; Image1.Picture.BitMap.Canvas.Draw(Form1.Left + RahmenbreiteLinks, Form1.Top + RahmenbreiteOben, BitMap); Finally BitMap.Free; End; End; |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Z.B. das wäre bestimmt hilfreich:
Delphi-Quellcode:
type
TForm1 = class(TForm) private { Private-Deklarationen } procedure WMHOTKEY(var Message: TWMHOTKEY); message WM_HOTKEY; public { Public-Deklarationen } end;
Delphi-Quellcode:
procedure TForm1.WMHOTKEY(var Message: TWMHOTKEY);
begin If (Message.HotKey = IDHOT_SNAPDESKTOP) then TuWasMitDesktopScreenshot; else If (Message.HotKey = IDHOT_SNAPWINDOW) then TuWasMitFensterScreenshot; end;
Delphi-Quellcode:
Genauere Infos gibts in der Windows SDK
RegisterHotKey(Handle, IDHOT_SNAPDESKTOP, 0, VK_SNAPSHOT);
RegisterHotKey(Handle, IDHOT_SNAPWINDOW, MOD_CONTROL, VK_SNAPSHOT); PS: Für diese beiden speziellen Hotkeys sind IDHOT_SNAPDESKTOP und IDHOT_SNAPWINDOW bereits vordefinierte Konstanten, es können dafür meines wissens keine anderen IDs verwendet werden. |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Ich habe mich nochmal im Forum umgesehen und habe eins gefunden, was garnicht so schwer scheint:
Delphi-Quellcode:
Das Problem ist, das ich in "BitBlt" nicht die richtigen Zahlen eingesetzt habe...
procedure TForm1.Button1Click(Sender: TObject);
var X, Y: Integer; begin Canvas.Handle := GetWindowDC(0); try X := Trunc((Form1.Width-Form1.ClientWidth) div 2); Y := Trunc((Form1.Height-Form1.ClientWidth) -X); Image1.Picture.Bitmap.Width := Form1.ClientWidth; Image1.Picture.Bitmap.Height:= Form1.ClientHeight; Image1.Picture.Bitmap.PixelFormat := pfDevice; BitBlt(Image1.Picture.Bitmap.Canvas.Handle, -Form1.Left+X, -Form1.Top+Y, Pred(Form1.ClientWidth), Pred( Form1.ClientHeight), Canvas.Handle, Form1.Left, Form1.Top, Image1.Picture.Bitmap.Canvas.CopyMode); finally ReleaseDC(0, Canvas.Handle); end; end; Ich möchte nur den in mein TImage "übernehmen", den die Form bedeckt. Könnt ihr mir helfen? :lol: |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Zitat:
Hallo, ich habe diesen etwas angestaubten Beitrag ausgegraben, weil er dem was ich brauche bisher am nächsten kommt. Ich habe versucht ein kleines screengrabbertool zu schreiben mit dem man ein transparentes Wasserzeichen auf einen beliebigen Hintergrund blenden und davon dann einen screenshot machen kann. Soweit habe ich das auch hinbekommen - nur beim besagten screenshot wurde das alpha verblendete Wasserzeichen nicht angezeigt, diese Möglichkeit hier ist die erste die funktioniert. Mir gefällt es aber nicht, über die Zwischenablage gehen zu müssen die ja dadurch gelöscht wird - deswegen nun meine Frage, gibt es noch eine andere - einfache - Möglichkeit einen Screenshot zu erzeugen der auch transparente Forms mitnimmt? Da ich erst seit 2 Wochen delphi mache und sonst wenig Vorkenntnisse habe, wäre ich für anfängefreundliche Antworten (eventuell mit Links zu Beispielen) dankbar. :duck: Gruß |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
willst du einen Screenshot machen und diesen anzeigen in einem Form, welches wie ein Bilderrahmen aussieht, oder willst du nur dass ein Rahmen draufgemalt wird, um es bisschen aufgepepter zu speichern.
ersteres geht mit Regions, siehe Himitsu's post letzteres kannst per Canvas des Bitmap-Objektes machen. den screenshot selbst kann man z.b. so:
Delphi-Quellcode:
HTH Frank
procedure TAlarmDataList.GetScreenBitmap(r:TRect;bmp:TBitmap);
var FHdc:HDC; begin FHdc:=GetDC(0); bmp.width:=r.right-r.left; bmp.height:=r.Bottom-r.top; bmp.pixelformat:=pf24Bit; bitblt(bmp.canvas.handle,0,0,bmp.width,bmp.height,FHdc,r.left,r.top,srcCopy); end; |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Liste der Anhänge anzeigen (Anzahl: 1)
d
Zitat:
ich habe mal ein beispielprogramm geschrieben damit man sieht was ich meine. den ersten button drücken um ein alpha blend form aufzurufen, den zweiten um einen screenshot zu machen (mit deinem code). du wirst sehen, das alpha fenster taucht im screenshot nicht auf. zur zeit löse ich das problem in meinem projekt indem ich den druck auf die drucken taste simuliere, das entstehende bitmap aus der zwischenablage lade und nachträglich beschneide. Das funktioniert für einzelne screenshots wunderbar, leider ist es aber zu langsam um damit an motion capture zu denken. ich wüsste gern einen weg wie man entweder gleich alphablendiert kopiert oder nachträglich alphablendingmässig in ein canvas malt. lieben Gruß |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
probiers mal so (von
![]()
Delphi-Quellcode:
//Edit:
const
CAPTUREBLT = $40000000; DC := GetWindowDC(0); try BitBlt(BackBuf.Canvas.Handle, 0, 0, BackBuf.Width, BackBuf.Height, DC, 0, 0, SRCCOPY or CAPTUREBLT); finally ReleaseDC(0, DC); end; das mit dem Wasserzeichen versteh ich nicht ganz...wozu brauchst du da alphablending? warum nicht einfach die normalen Canvas-Methoden, um Text/Rahmen hinzumalen? HTH Frank |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Zitat:
|
Re: Durchsichtiges Fenster (nicht Alpha Blend)
deswegen hab ich die Quelle mit genannt...da steht die deklaration der Konstante, habs aber oben jetzt auch ergänzt.
bitte meine Fragen im Edit beachten. Gruß Frank |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Zitat:
den link hatte ich nicht gesehen, da ich auf der seite aber net registriert bin nutzt er mir auch nichts. :gruebel: wie das ganze gemeint ist, erklärt mein beispielprogramm. warum ich nicht die "normalen canvas funktionen" verwende könnte daran liegen, das ich (delphi anfänger) sie bisher nicht gefunden habe :) (und glaub mir, ich hab gesucht wie verrückt nach einer möglichkeit) nichtsdestotrotz hat jetzt deine lösung funktioniert und ich bin glücklich! VIELEN VIELEN VIELEN DANK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :thumb: :thumb: :thumb: Es scheint allerdings eine geringe abweichung in der helligkeit zu geben, ich werde das jetzt ausgiebig testen und hoffe damit klarzukommen. Wenn du mir die "normalen canvas funktionen" mit denen das auch gehen würde verrätst probier ich die auch gerne aus :) lieben gruß |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Zitat:
Zitat:
Gruß Frank |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Bin ich der einzige, bei dem der Thread im FF und IE zerrissen ist?
//Edit: Die erste Seite meine ich.. :stupid: |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Zitat:
Gruß Frank |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Bei mir auch aber ab #16 gehts wieder :?:
MfG Mikescher |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Einmal gegentreten, schon passt die Darstellung wieder. :stupid:
|
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Zitat:
Gruß Frank |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Zitat:
//Edit: @Frank: Der W3C Validator lieferte defekte Tabellen-Tags, insgesamt 9 Fehler und 423 Warnungen. :shock: Jetzt sind es nur noch 5 Fehler und 423 Warnungen.. :stupid: |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Zitat:
Streng genommen kann ich Dir gar nicht sagen, warum manchmal nur kleine Tags fehlen und nicht gleich halbe Beiträge. is' eben so ... ;-) |
Re: Durchsichtiges Fenster (nicht Alpha Blend)
Zitat:
also ich bin ein wenig am Verzweifeln, und zwar versuche ich mithilfe dieses codes eine art kurzen "motion grabber" zu schreiben. Ich bekomme es aber nicht sauber hin... wenn ich alles in eine procedur packe, dann kommt nach ca. 70 ganzbildjpgs (~á400kb) irgendwas mit "Für diesen Befehl ist nicht genügend Speicher vorhanden". Das kann aber eigentlich nicht sein... denn wenn ich bilder von der platte lade (habsch getestet) dann kann ich 4500 (~á400kb) problemlos laden, bis es dann zu stottern anfängt und irgendwann die fehlermeldung "Nicht genügend Arbeitsspeicher" kommt. (wer jetzt die stirn runzelt sei einigermaßen beruhigt: ziel ist es ca. 3600 bilder à 100-200kb aneinanderzureihen sollte also rechnerisch gehen) versucht hatte ich es bisher mit einem array:
Delphi-Quellcode:
dann wollte ich das ganze durch eine schleife rennen lassen die ungefähr folgendes macht:
jpglisted: array of TJpegimage;
Delphi-Quellcode:
ich hab zwischendrin auch mal versucht der datenflut über tmemorystream oder tfilestream herr zu werden aber beide prozesse brauchen pro jpgbild ~200ms was zu langsam ist.
procedure TForm1.newscreenshot(sender:TObject);
var screenshotjpg: TJpegimage; DC:HDC; screenshot: TBitmap; i:integer; const CAPTUREBLT = $40000000; begin DC := GetWindowDC(0); try screenshot := TBitmap.Create; screenshot.Width := form2.Shape1.Width; screenshot.Height:= form2.Shape1.height; screenshot.PixelFormat := pfDevice; finally BitBlt(screenshot.Canvas.Handle, 0, 0, screenshot.Width, screenshot.Height, DC,(form2.Left+form2.Shape1.left), (form2.Top+form2.shape1.top), SRCCOPY or CAPTUREBLT); releaseDC(0,DC); jpglisted[geschafft] := Tjpegimage.Create; try jpglisted[geschafft].assign(screenshot); finally screenshot.Free; screenshot:=nil; //spätestens ab hier sollte doch nur noch das jpg im speicher sein... end; end; ich vermute mal das ich das jpglisted[geschafft] noch .freeen müsste und das bild vorher (sauber getrennt) woanders hin übergeben müsste... aber ich weiss net wie das geht :( arrays, streams, und all das ist neuland für mich, ich bin Anfänger :) Deshalb würde ich mich über anfängerfreundliche Antworten freuen, vielleicht hat ja auch jemand lust mir den Mentor via MSN zu machen :D das wär schon klasse mal zwischendrin jemand fragen können mit Ahnung. lieben Gruß //EDIT: was mir beim testen eben aufgefallen ist, wenn ich die bilder einzeln einer Tjpegliste hinzufüge wächst mein Programm im Taskmanager überhaupt nicht.... es bleibt bei 3822 byte obwohl ich 50 bilder hinzufüge... (bei 75 steigt er dann wieder aus und behauptet keinen speicher mehr für den befehl zu haben) kann es sein das er die bilder nicht im arbeitsspeicher sondern in irgendeinem viel kleineren puffer abzulegen versucht??? Wenn ich bilder (mit dem gleichen programm) von platte (in die gleiche liste) lade wird brav bei jedem neu geladenen bild auch das projekt im taskmanager größer.... // EDIT2... ok, nachdem ich jetzt noch mehr rumprobiert und ausprobiert habe bin ich mir fast sicher: die von mir erzeugten bilder liegen in irgendeinem resourcenpuffer und solange ich sie nicht 1.) rausschreibe 2.) freigebe 3.) wieder reinlade lassen sie sich auch durch nichts in meiner macht stehende dazu bringen in die gewaltigen hallen meines arbeitsspeichers zu hüpfen, sondern blockieren lieber weiter die engen flure... jetzt hab ich zwar ne lösung (savetofile -> free -> loadfromfile) aber das ist doch krank und dauert fast ne halbe sekunde pro bild... gibts keinen befehl der Delphi zwingt ein bmp aus dem device context in den arbeitsspeicher zu schieben um den DC dann sauber deleten zu können? über anfängerfreundliche antworten würde ich mich wie immer sehr freuen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:12 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