Wie ein Loch ins Form stanzen ?

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Antworten
Frank Ranis
Beiträge: 201
Registriert: Do 24. Jan 2013, 21:22

Wie ein Loch ins Form stanzen ?

Beitrag von Frank Ranis »

Hallo,

Ich möchte einen Picture-Picker bauen .

Urzustand ist ein normales Form mit einer Paintbox , die am Formrahmen verankert ist.
Auf Button-Klick soll an der Position der Paintbox ein Loch entstehen und bei erneutem Click alles in den Ursprung zurück versetzt werden.
Wichtig ist auch , das das Form-Resize sowohl mit Loch drinn , als auch im Orginalzustand funktionieren muss.
Das ganze Form muss sich auf dem Bildschirm verschieben lassen .

Das Form soll dann in der Application z.B. per Funktionstaste F-X aufpoppen und Stay-On-Top sein , also über der App schweben.
Das Form mit dem Loch darin sollte dann wie ein Bilderrahmen positioniert und vergrößert werden können , um einen bestimmten Bildausschnitt per Screenshot picken zu können .
Während der Screnn-Shot gemacht wird , sollte die Form kurz unsichtbar gemacht werden , damit man die Form selber nicht mit im Screenshot-Bild hat .
Ist das Screenshot-Bild gemacht , soll die Form auf Normalmodus schalten und das Pickbild in die Paintbox zeichnen .
Dann kann man dort noch was reinmalen und alles wegspeichern.

Bezüglich des Lochs im Form habe auch mal einen ersten Code geproggt , siehe unten .
Verwende dafür die Funktionen (CreateRectRgn , CombineRgn , SetWindowRgn) .

Es wird ein Loch gemacht und auf erneuten Button-Klick zurück in den Orginalzustand.
Problem:
Die Funktion SetWindowRgn erzeugt ein Aussehen wie zu Windows XP-Zeiten.
Positionen der Komponeneten werden verschoben , der Form-Rahmen wird rechts und unten abgeschnitten , so das man die Form nicht Resizen kann.

1) Kann man das ändern ?
2) Gibt es eine andere Möglichkeit ein Loch zu machen ?
3) Sollte unter WIN und Linux laufen

Gruß

Frank

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
 Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls ,
 LCLIntf,LCLType, ExtCtrls;

type

 { TForm1 }

 TForm1 = class(TForm)
  Button1: TButton;
  PaintBox1: TPaintBox;
  procedure Button1Click(Sender: TObject);
  procedure FormCreate(Sender: TObject);
  procedure PaintBox1Paint(Sender: TObject);
 private

 public
  loch:boolean;
 end;

var
 Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  region1, region2: hrgn;
begin
 if loch
  then
   begin
    region1 := CreateRectRgn(0, 0, Width, Height);
    region2 := CreateRectRgn(paintbox1.Left,
                             paintbox1.top,
                             paintbox1.Width,
                             paintbox1.Height);
    CombineRgn(region1, region1, region2, RGN_DIFF);
    SetWindowRgn(Handle, region1, True);
   end
  else
   SetWindowRgn(Handle,0,True);

 loch:= not loch;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 loch:=true;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
 paintbox1.Canvas.Brush.Color:=cllime;
 paintbox1.Canvas.FillRect(Rect(0,0,paintbox1.width,paintbox1.height));
end;

end.
Picture_Picker_1.zip
(105.98 KiB) 70-mal heruntergeladen
www.flz-vortex.de

ArchChem
Beiträge: 82
Registriert: Mo 11. Jul 2022, 10:41

Re: Wie ein Loch ins Form stanzen ?

Beitrag von ArchChem »

Guten Morgen,

ich würde für das Loch eine zweite Form erstellen, und dann diese bei Bedarf anzeigen lassen. Hierfür kannst du die Funktionen hide und Show verwenden. Also exemplarisch, sei die zweite Form frmLoch:

Code: Alles auswählen

If Loch then
begin
  form1.hide;
  frmLoch.show;
  // Mache frmLoch zum Loch [...]
  
  // Wenn Fertig
  frmLoch.hide;
  form1.show;
  Loch := not Loch;
end;
Ich kann den Code leider zur Zeit nicht testen, aber mit diesem Ansatz würdest du Form1 (deine Anzeigeform) in Ruhe lassen und falsche Darstellungen vermeiden.

Viele Grüße!

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Wie ein Loch ins Form stanzen ?

Beitrag von theo »

Man kann das Formular mit

Code: Alles auswählen

AlphaBlend:=true;
AlphaBlendValue:=100; //Z.B.
Semi-transparent machen.
Somit kann man auch hindurchsehen und das Formular verhält sich sonst wie normal.

Frank Ranis
Beiträge: 201
Registriert: Do 24. Jan 2013, 21:22

Re: Wie ein Loch ins Form stanzen ?

Beitrag von Frank Ranis »

Hallo ,

vielen Dank für eure Antworten.

@ArchChem
Deine Gedankengänge habe ich leider nicht verstanden.

@theo
Das Alpha-Blending funktioniert nicht für meine Idee.

Ich möchte die Anwendung unter dem Bilderrahmen voll bedienen können , muß also durch das Loch mit der Maus klicken können.
Beispiel:
Meine Hauptanwendung hat ein MainMenu , das aufklappt wenn ich mit der Maus draufklicke .
Von diesem Hauptfenster mit aufgeklappten Menü will ich dann einen Screenshot machen.
Mein Picture-Picker ist ja duch StayOnTop immer im Vordergrund und solange er sichtbar ist , soll dort ein Timer mit einer GetKeyState-Abfrage laufen.
Und dann z.B. auf Funktionstaste F4 reagieren.
Um halt nicht den Focus auf der Hautanwendung zu verlieren , weil dann klappt ja das Menü wieder zu und ich habe kein Bild davon.

Danach habe ich dann ein Bild , das in der Paintbox angezeigt wird.
Hier möchte ich dann noch ein paar Kreise um interessante Bildbereiche malen (z.B. einen Kreis um einen Menüeintrag) .
Eventuell noch einen Beschreibungstext in das Bild einfügen .
Das fertige Bild (in der Größe der Paintbox) kann ich dann entweder wegspeichern oder in die Zwischenablage transportieren.
Das ganze soll dazu dienen , Bilder für meine HTML-Hilfen zu erstellen.
Die bisherige Vorgehensweise , ist voll ätzend.
1) Screenshot mit ALT-DRUCK erstellen .
2) Paint oder so was aufmachen und Bild aus der Zwischenablage einfügen.
3) Bild passig schneiden.
4) Interssante Bereiche einkringeln und eventuell noch einen Text draufmalen.
5) Abspeichern.

Die Punkte 1-3 will ich mir ersparen.

So etwa soll dann die Timerroutine aussehen:

Code: Alles auswählen

// Tastatur Überwachung
procedure TForm1.Timer1Timer(Sender: TObject);
var ScreenDC:HWND;
begin
 // Screenshot machen
 if (GetKeyState(115) and $8000 <> 0) and // F4 115
    (self.Visible) and
    (mode=pick)
  then
   begin
    // weitere Timerereignisse verhindern
    timer1.Enabled:=false;
 
    drawpos:=Paintbox1.ClientToScreen(Point(0,0)); // Festhalten für die Paintboxausgabe
 
    self.Visible:=false; // Picker-Form unsichtbar machen
 
    sleep(200); // etwas warten , bis wirklich alles vom Pick-Form unsichtbar ist
 
    ScreenDC := GetDC(0);
    screenbmp.LoadFromDevice(ScreenDC); // Screenshot vom Bildschirm machen
 
    self.Visible:=true; // Picker-Form wieder sichtbar machen
    ReleaseDC(0,ScreenDC); // Handle ScreenDC freigeben
 
    caption:=titel+' gepickt';
    // in den Drawmodus schalten
    DrawButton.Click;
   end;
end;

Gruß

Frank
www.flz-vortex.de

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Wie ein Loch ins Form stanzen ?

Beitrag von theo »

Warum nimmst du nicht einfach Gimp?
https://www.gimp.org/downloads/

gimp_scrs.png
gimp_scrs.png (145.31 KiB) 1717 mal betrachtet

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wie ein Loch ins Form stanzen ?

Beitrag von Winni »

Hi!

Ich hab Dir mal kurz quick & dirty ein Loch in eine Form gestanzt.

Zu beachten: Nachdem eine Region gesetzt ist, ist der TitleBar nicht mehr vorhanden.
Deshalb hab ich mal kurz den Mechanismus zum Verschieben auf die ganze Form gelegt.
Außerdem braucht es deshalb einen Exit-Button (Für alle, die sich mit Alt-F4 nicht auskennen)

Screenshot + Project anbei.
Rest must Du selbst machen .
Zu heiß.

Winni
Dateianhänge
Loch.png
Loch.png (82.19 KiB) 1708 mal betrachtet
Loch.zip
(140.51 KiB) 87-mal heruntergeladen

Frank Ranis
Beiträge: 201
Registriert: Do 24. Jan 2013, 21:22

Re: Wie ein Loch ins Form stanzen ?

Beitrag von Frank Ranis »

Hallo ,

@Winni
Vielen Dank für die Demo .
Leider sind dann alle Vorzüge des Forms (Verschieben , Resize usw.) dahin , werde aber damit mal ein wenig spielen.

@theo
>>>>
Warum nimmst du nicht einfach Gimp
<<<<
Auch das werde ich mir mal anschauen .

Ich danke euch für die Antworten.

Gruß

Frank
www.flz-vortex.de

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Wie ein Loch ins Form stanzen ?

Beitrag von theo »

Frank Ranis hat geschrieben:
Fr 5. Aug 2022, 05:52
@theo
> Warum nimmst du nicht einfach Gimp
Auch das werde ich mir mal anschauen .
Der Menüpunkt heisst bei Gimp: Datei -> Erstellen -> Bildschirmfoto.

Gimp ist eigentlich bei den meisten Linux Distris via Paketmanager dabei.

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Wie ein Loch ins Form stanzen ?

Beitrag von charlytango »

bin da jetzt kein Spezialist für außergewöhnliche Fenstersteuerung, aber vielleicht sind ein paar inputs Ausgangspunkt für eine Recherche:

Da gab es unter Delphi einige Komponenten die sich mit Formularen beschäftigten
https://torry.net/pages.php?id=94

Wenn ich mich richtig erinnere war da bei Turbopower auch mal was dabei.
https://sourceforge.net/directory/?q=turbopower

Möglicherweise ist da einiges dabei was als Ideengeber und Codebasis taugt

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wie ein Loch ins Form stanzen ?

Beitrag von Winni »

Frank Ranis hat geschrieben:
Fr 5. Aug 2022, 05:52
Hallo ,

@Winni
Vielen Dank für die Demo .
Leider sind dann alle Vorzüge des Forms (Verschieben , Resize usw.) dahin , werde aber damit mal ein wenig spielen.
Hi!

Verschieben hab ich Dir eingebaut - wie erwähnt:

Irgendwo auf die Form klicken und ziehen.

Für das Resize müsste man sich eine eigene Mimik bauen z.B. mit festen Werten in Abhängikeit von der Bildschirmgröße.

Das ist leider seit Delphi-Zeiten so: Wenn man mittels SetWindowRgn der Form ein anderes Aussehen gibt, wird der TitleBar deaktiviert,

Winni

Antworten