Form mit selbstgemachtem TitleBar
- 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
Form mit selbstgemachtem TitleBar
Hallo!
Im internationalen Forum tauchte die Frage auf, ob man einen Button (oder andere Komponenten) in dem TitleBar unterbringen kann.
Das ist ein wundes Thema bei Lazarus.
Unter Windows kommt man per API-Calls mühselig an den TitleBar ran.
Unter Linux ist da keine Chance, da der TitleBar "Eigentum" des Window-Managers ist, der zum Desktop gehört und nicht zu Lazarus.
Da muss man sich ein Workaround schnitzen.
Mit BorderStyle = bsNone wird der TitleBar unsichtbar.
Mit einem Panel oben in der Form schnitzt man sich selber einen.
Darauf kommt ein Timage, in das die verschieden Icon-Sets für das System-Menü geladen werden können.
Da könnte dann auch der gewünschte Button hin.
Die Demo hat die Möglichkeit für 6 verschiedene Icon-Sets: 3 KDE und 3 Windows.
Screenshot und Project anbei.
Winni
Im internationalen Forum tauchte die Frage auf, ob man einen Button (oder andere Komponenten) in dem TitleBar unterbringen kann.
Das ist ein wundes Thema bei Lazarus.
Unter Windows kommt man per API-Calls mühselig an den TitleBar ran.
Unter Linux ist da keine Chance, da der TitleBar "Eigentum" des Window-Managers ist, der zum Desktop gehört und nicht zu Lazarus.
Da muss man sich ein Workaround schnitzen.
Mit BorderStyle = bsNone wird der TitleBar unsichtbar.
Mit einem Panel oben in der Form schnitzt man sich selber einen.
Darauf kommt ein Timage, in das die verschieden Icon-Sets für das System-Menü geladen werden können.
Da könnte dann auch der gewünschte Button hin.
Die Demo hat die Möglichkeit für 6 verschiedene Icon-Sets: 3 KDE und 3 Windows.
Screenshot und Project anbei.
Winni
- Dateianhänge
-
- NoTitleBar.png (36.25 KiB) 2125 mal betrachtet
-
NoTitleBar.zip
- (198.14 KiB) 99-mal heruntergeladen
-
- Beiträge: 219
- Registriert: Mo 3. Jan 2011, 13:34
- OS, Lazarus, FPC: Win11 (L 3.0 FPC 3.2.2)
- CPU-Target: 64Bit
- Wohnort: Nürnberg
Re: Form mit selbstgemachtem TitleBar
Ein paar dumme Fragen seien erlaubt:
1) Welche Bedeutung hat das rote Rectangle das im FormPaint Ereignis gezeichnet wird?
Ich denke, das Rectangle soll die Fenstergröße veranschaulichen, die durch den borderStyle=bsNone verloren gegangen ist.
Schon stellt sich die zweite Frage:
2. Warum wird das rectangle mit
gezeichnet und nicht mit
3. und viel interessantere Frage :
Wie gedenkst Du das FormResizing zu realisieren?
4.Frage: Was passiert im FormCreate Ereignis?
Ohne Kommentare kann ich die beabsichtigten "Features" nicht herauslesen. Wäre hilfreich, wenn Du erwartest, dass jemand verstehen soll, was da passiert.
Zum Beispiel mit einem TBGRAIconCursor habe ich bisher noch nie gearbeitet. Ich weiss gar nicht wozu der gut sein soll.
Dann wird das Application Icon in einen MemStream geladen, und der memStream vom TBGRAIcoCursor wieder gelesen.
Dann wird auch noch eine TBGRABitmap erzeugt und "verwurschtelt". (Sorry für meine Ausdrucksweise)
Das ist mir alles zu rätselhaft, mit Kommentaren könnte man besser verstehen, was Du dem Quellcodeleser sagen willst.
Vor allem: Was hat das mit dem Thema "selbstgemachte Titlebar" zu tun?
Hoffentlich bist Du mir wegen meiner dummen Fragen nicht böse.
Ich finde das Thema "Form mit selbstgemachtem Titlebar" wunderschön und sehr interessant.
Aber die Lösung mit borderstyle=bsNone und selbst gezeichnetem Panel als Titlebar ist auch nicht gerade neu, wenn Du ehrlich bist.
Und Dein Quellcode hat für mich zu viele Rätsel
Nix für ungut
Fritz
1) Welche Bedeutung hat das rote Rectangle das im FormPaint Ereignis gezeichnet wird?
Code: Alles auswählen
procedure TForm1.FormPaint(Sender: TObject);
var R : TRect;
begin
Canvas.Pen.Color := clRed;
R := Rect(1,1,width-1,Height-1);
Canvas.Rectangle (R);
end;
Schon stellt sich die zweite Frage:
2. Warum wird das rectangle mit
Code: Alles auswählen
Rect(1,1,width-1,Height-1);
Code: Alles auswählen
Rect(0,0,width,Height);
Wie gedenkst Du das FormResizing zu realisieren?
4.Frage: Was passiert im FormCreate Ereignis?
Code: Alles auswählen
procedure TForm1.FormCreate(Sender: TObject);
var
x,xy, xyDest,i : Integer;
R : Trect;
ICur : TBGRAIconCursor;
MemStream: TMemoryStream;
bmp : TBGRABitmap;
begin
// Icon
ICur := TBGRAIconCursor.Create;
MemStream:= TMemoryStream.Create;
Application.Icon.SaveToStream(MemStream);
MemStream.Position:=0;
ICur.LoadFromStream(MemStream);
bmp := TBGRABitmap.Create;
BGRAreplace (bmp, ICur.GetBitmap(0));
xy := Image1.Height;
BGRAreplace (bmp,bmp.resample(xy,xy));
bmp.draw(Image1.Canvas,0,0,false);
bmp.free;
ICur.Free;
MemStream.free;
(*
xy := application.Icon.Height;
tmp := TBGRAbitmap.Create (xy,xy);
R := Rect(0,0,xy,xy);
tmp.Canvas.CopyRect (R,application.Icon.Canvas,R);
xyDest := Image1.Height;
BGRAreplace (tmp,tmp.resample(xyDest,xyDest));
tmp.Draw(Image1.canvas,0,0);
tmp.free;
*)
showTBarIcons;
for i := 0 to high(Inames) do
Icons.Items.add (Inames[i]);
Icons.ItemIndex := 0;
SelectIconSet (0);
end;
Zum Beispiel mit einem TBGRAIconCursor habe ich bisher noch nie gearbeitet. Ich weiss gar nicht wozu der gut sein soll.
Dann wird das Application Icon in einen MemStream geladen, und der memStream vom TBGRAIcoCursor wieder gelesen.
Dann wird auch noch eine TBGRABitmap erzeugt und "verwurschtelt". (Sorry für meine Ausdrucksweise)
Das ist mir alles zu rätselhaft, mit Kommentaren könnte man besser verstehen, was Du dem Quellcodeleser sagen willst.
Vor allem: Was hat das mit dem Thema "selbstgemachte Titlebar" zu tun?
Hoffentlich bist Du mir wegen meiner dummen Fragen nicht böse.
Ich finde das Thema "Form mit selbstgemachtem Titlebar" wunderschön und sehr interessant.
Aber die Lösung mit borderstyle=bsNone und selbst gezeichnetem Panel als Titlebar ist auch nicht gerade neu, wenn Du ehrlich bist.
Und Dein Quellcode hat für mich zu viele Rätsel
Nix für ungut
Fritz
- 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: Form mit selbstgemachtem TitleBar
Hi!
Zu Deinen Fragen:
ist notwenig: Bei BorderStyle = bsNone zeigt er keinen TitleBar mehr an, es geht aber auch die Border flöten - daher der Name. Muss man also selbst zeichnen.
Und das (+1,+1,-1,-1) mach ich weil das einen schöneren Rand ergibt: 1 Pixel Form, dann 1 Pixel Border, dann der Rest der Form.
"Design für Arme" kann man das auch nennen.
FormCreate macht Folgendes:
Ich lutsche das Icon der Application (Projecteinstellungen, erste Seite) per Memorystream in eine BGRAIconCursor.
Dann hole ich die BGRABitmap aus dem BGRAIconCursor und bringe es auf das richtige Format. Dann male ich die Bitmap links oben auf das Image in dem selbstgemachten Taskbar.
Könnte man auch alles mit TBitmap und TIcon machen, aber ich hatte gerade kein vernünftges resize zur Hand. Und das fällt bei BGRAbitmap aus der Tüte.
Ansonsten: Beim resize kümmern sich die richtigen Anchors um das Taskbar-Panel und de Elementen da drauf. Da kümmert sich PanelOnpaint nur noch um die Caption - immer scön zentriert.
Ausreichend Antwort??
Winni
Zu Deinen Fragen:
Code: Alles auswählen
Rect(1,1,width-1,Height-1);
Und das (+1,+1,-1,-1) mach ich weil das einen schöneren Rand ergibt: 1 Pixel Form, dann 1 Pixel Border, dann der Rest der Form.
"Design für Arme" kann man das auch nennen.
FormCreate macht Folgendes:
Ich lutsche das Icon der Application (Projecteinstellungen, erste Seite) per Memorystream in eine BGRAIconCursor.
Dann hole ich die BGRABitmap aus dem BGRAIconCursor und bringe es auf das richtige Format. Dann male ich die Bitmap links oben auf das Image in dem selbstgemachten Taskbar.
Könnte man auch alles mit TBitmap und TIcon machen, aber ich hatte gerade kein vernünftges resize zur Hand. Und das fällt bei BGRAbitmap aus der Tüte.
Ansonsten: Beim resize kümmern sich die richtigen Anchors um das Taskbar-Panel und de Elementen da drauf. Da kümmert sich PanelOnpaint nur noch um die Caption - immer scön zentriert.
Ausreichend Antwort??
Winni
-
- Beiträge: 219
- Registriert: Mo 3. Jan 2011, 13:34
- OS, Lazarus, FPC: Win11 (L 3.0 FPC 3.2.2)
- CPU-Target: 64Bit
- Wohnort: Nürnberg
Re: Form mit selbstgemachtem TitleBar
Ausreichend Antwort.
Zur Abwechslung ein bißchen Lob, weil ja scheinbar niemand das Demo-Projekt von Dir kommentiert hat:
1. Sehr interessant finde ich das Feature, das die FontFarbe der Titlebar abhängig von der Farbe der Titlebar gesetzt wird
2. Weiters sehr interessant ist die Technik, mit der das Verschieben der MainForm realisert wurde (Weil ja kein Fenstertitel da ist, kann man darüber auch das Fenster nicht verschieben).
Man merkt sich beim MouseDown, wo man hingeklickt hat...
...und beim MouseMove verschiebt man dann entsprechend das ganze Fenster.
Die Frage aus dem internationalen Forum, ob man einen Button in der Titlebar unterbringen kann, hast Du aber bis jetzt nicht beantwortet.
Das Demo-Projekt zeigt lediglich, wie eine Grafik in die Titlebar platziert wird.
Aber wie man einen Button auf ein Panel setzt, sollte jeder Lazarus-Anwender beherrschen, das wäre eigentlich nicht erklärungsbedürftig, oder siehst Du hier ein Problem?
Vielleicht erweitert jemand das Demo-Programm um die Möglichkeit, die Formgröße mit der Mouse zu verändern, durch Anpacken und Ziehen an den FormRändern?
Viele Grüße
Fritz
Zur Abwechslung ein bißchen Lob, weil ja scheinbar niemand das Demo-Projekt von Dir kommentiert hat:
1. Sehr interessant finde ich das Feature, das die FontFarbe der Titlebar abhängig von der Farbe der Titlebar gesetzt wird
Code: Alles auswählen
Panel1.Color := img.GetPixel(0,0);
col:= img.GetPixel(0,0);
if col.red+col.green+col.blue < 200 then
Panel1.Canvas.Font.Color := clWhite
else
Panel1.Canvas.Font.Color := clBlack;
Man merkt sich beim MouseDown, wo man hingeklickt hat...
...und beim MouseMove verschiebt man dann entsprechend das ganze Fenster.
Code: Alles auswählen
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ssLeft in Shift then
begin
xoff := x;
yOff := y;
end;
end;
procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if ssLeft in Shift then
begin
left := Left+x -Xoff;
top := top +y - yoff;
end;
end;
Das Demo-Projekt zeigt lediglich, wie eine Grafik in die Titlebar platziert wird.
Aber wie man einen Button auf ein Panel setzt, sollte jeder Lazarus-Anwender beherrschen, das wäre eigentlich nicht erklärungsbedürftig, oder siehst Du hier ein Problem?
Vielleicht erweitert jemand das Demo-Programm um die Möglichkeit, die Formgröße mit der Mouse zu verändern, durch Anpacken und Ziehen an den FormRändern?
Viele Grüße
Fritz
- 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: Form mit selbstgemachtem TitleBar
Hallo!
Danke für die Blumen!
ad 1: Ja, das ist "poor mans lightnig". Igendwas muss da ja gemacht werden, bevor schwarze Buchstaben auf duunkelgrauem Hintergrund stehen. Korrekt wäre die Berechnung unter Einbeziehung der Leuchtkraft der einzelnen Farben gewesen, aber ist ja nur ne Demo.
ad 2: Das hab ich gelernt, als ich (noch unter Delphi) probiert habe, wie man einer Form eine beliebige Form (mittels Polygon) geben kann. Die haben dann auch keinen TitleBar mehr. Und man muss sie ja bewegen können.
Das Plazieren von einem Button auf dem TitleBar-Panel sollte ja nun trivial sein.
Da ich mich aber seit den frühen X-Server-Tagen und Win 3.1 über das Gefummel an den Rändern zum Resizen ärgere, hätte ich aber einen anderen Vorschlag: Zwei SpinEdits um die Größe der Form in X- und Y-Richtung zu ändern. Auf dem neuen TitleBar.
Auch graphisch kann man recht einfach zuschlagen: z.B. einen Farbverlauf in das PanelOnpaint zaubern (Canvas.GradientFill).
Winni
Danke für die Blumen!
ad 1: Ja, das ist "poor mans lightnig". Igendwas muss da ja gemacht werden, bevor schwarze Buchstaben auf duunkelgrauem Hintergrund stehen. Korrekt wäre die Berechnung unter Einbeziehung der Leuchtkraft der einzelnen Farben gewesen, aber ist ja nur ne Demo.
ad 2: Das hab ich gelernt, als ich (noch unter Delphi) probiert habe, wie man einer Form eine beliebige Form (mittels Polygon) geben kann. Die haben dann auch keinen TitleBar mehr. Und man muss sie ja bewegen können.
Das Plazieren von einem Button auf dem TitleBar-Panel sollte ja nun trivial sein.
Da ich mich aber seit den frühen X-Server-Tagen und Win 3.1 über das Gefummel an den Rändern zum Resizen ärgere, hätte ich aber einen anderen Vorschlag: Zwei SpinEdits um die Größe der Form in X- und Y-Richtung zu ändern. Auf dem neuen TitleBar.
Auch graphisch kann man recht einfach zuschlagen: z.B. einen Farbverlauf in das PanelOnpaint zaubern (Canvas.GradientFill).
Winni
- 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: Form mit selbstgemachtem TitleBar
Hi!
Ich hab dann mal meine Idee umgesetzt:
SpinEdits für Breite und Höhe der Form im TitleBar.
Project und Screenshot anbei
Winni
Ich hab dann mal meine Idee umgesetzt:
SpinEdits für Breite und Höhe der Form im TitleBar.
Project und Screenshot anbei
Winni
- Dateianhänge
-
- NoTitleBarSpins.png (36.99 KiB) 1925 mal betrachtet
-
NoTitleBar01.zip
- (229.73 KiB) 91-mal heruntergeladen
-
- Beiträge: 219
- Registriert: Mo 3. Jan 2011, 13:34
- OS, Lazarus, FPC: Win11 (L 3.0 FPC 3.2.2)
- CPU-Target: 64Bit
- Wohnort: Nürnberg
Re: Form mit selbstgemachtem TitleBar
Ich habe einen hervorragenden Artikel gefunden, wie man unter Delphi eine "Form mit selbstgemachtem Titlebar" erstellt.
Siehe hier: https://medium.com/@vuio/delphi-borderl ... 2538e3ec48
Den darin enthaltenen Delphi-Quellcode konnte ich in Delphi kompilieren und das Programm zeigt das im Artikel beschriebene Verhalten.
Als Lazarus-Jünger habe ich dann versucht diesen Delphi-Quellcode in Lazarus/Freepascal zu übersetzen.
Ist mir gelungen (bitte kein Lob dafür).
Leider verhält sich das Lazarus-Programm nicht wie gewünscht.
Irgendwie wird die message WM_NCCALCSIZE nicht ausgelöst, deshalb wird die Titelbar nicht "weggepinselt" sondern bleibt beharrlich zu sehen.
Kann mir jemand erklären, warum sich mein Lazarus-Programm so anders als das Delphi-Programm verhält?
Siehe hier: https://medium.com/@vuio/delphi-borderl ... 2538e3ec48
Den darin enthaltenen Delphi-Quellcode konnte ich in Delphi kompilieren und das Programm zeigt das im Artikel beschriebene Verhalten.
Als Lazarus-Jünger habe ich dann versucht diesen Delphi-Quellcode in Lazarus/Freepascal zu übersetzen.
Ist mir gelungen (bitte kein Lob dafür).
Leider verhält sich das Lazarus-Programm nicht wie gewünscht.
Irgendwie wird die message WM_NCCALCSIZE nicht ausgelöst, deshalb wird die Titelbar nicht "weggepinselt" sondern bleibt beharrlich zu sehen.
Kann mir jemand erklären, warum sich mein Lazarus-Programm so anders als das Delphi-Programm verhält?
- Dateianhänge
-
BorderlessForm3.zip
- (127.17 KiB) 95-mal heruntergeladen