Einzelnen Beitrag anzeigen

VCLVirtuoso

Registriert seit: 12. Mär 2024
3 Beiträge
 
Delphi 12 Athens
 
#1

Verwendung von TTitleBarPanel mit ModalPopupMode := pmAuto

  Alt 20. Mär 2024, 14:26
Bei der Verwendung von TTitleBarPanel in Forms, die mit ShowModal aufgerufen werden, ist mir ein merkwürdiges Verhalten aufgefallen. Wenn Application.ModalPopupMode := pmAuto gesetzt ist (was ja bei neueren Delphi-Anwendungen standardmäßig der Fall ist), wird die Custom Titlebar beim zweiten Aufruf des Fensters nicht über die normale Titlebar gezeichnet, sondern darunter, als wäre sie nicht richtig zugewiesen (siehe Anhang). Beim ersten Aufruf des Fensters sieht alles korrekt aus.

Reproduzieren lässt sich der Fehler mit zwei Forms und einer Titlebar in Form2. Die Titlebar wird über  CustomTitlebar.Control := TitleBarPanel1 und CustomTitlebar.Enabled := True in Form2 zugewiesen. Öffnet man über den Button in Form1 nun Form2, schließt Form2 wieder und öffnet es dann nochmal, tritt der Fehler wie auf dem Bild auf.

Wenn unter TForm2.FormActivate die API-Methode SetWindowPos mit dem Parameter SWP_FRAMECHANGED aufgerufen wird, tritt das Problem nicht mehr auf. In komplexeren Fenstern führt das aber zu einem unschönen Flackern. Gibt es einen eleganteren Weg, den Fehler zu umgehen oder handelt es sich dabei um einen Bug in Delphi? pmAuto führt generell an verschiedenen Stellen zu Problemen (siehe https://stackoverflow.com/questions/...bug-workaround), was auch so in der Dokumentation steht, wird aber in unserer Anwendung benötigt, damit TCommonDialoge, sowie die dynamische Vorschau in der Windows-Taskleiste korrekt funktionieren.
Delphi-Quellcode:
program Project1;

uses
  Vcl.Forms,
  Unit1 in 'Unit1.pas{Form1},
  Unit2 in 'Unit2.pas{Form2};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.ModalPopupMode := pmAuto;
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Unit2;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.ShowModal;
end

end.
Delphi-Quellcode:
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.TitleBarCtrls;

type
  TForm2 = class(TForm)
    TitleBarPanel1: TTitleBarPanel;
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  protected
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

uses
Unit1;

procedure TForm2.FormActivate(Sender: TObject);
begin
  SetWindowPos(Handle, 0, Left, Top, Width, Height, SWP_FRAMECHANGED); // Diese Zeile behebt das Problem
end;

end.
Miniaturansicht angehängter Grafiken
doppeltetitlebar.png  
  Mit Zitat antworten Zitat