TFont, TFontDialg gibt SIGSEGV

Rund um die LCL und andere Komponenten
Antworten
Mathias
Beiträge: 6918
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

TFont, TFontDialg gibt SIGSEGV

Beitrag von Mathias »

Wen ich folgenden Code ausführe und die Schriftart verändere, gibt es bei Programmende ein SIGSEGV.
Weise ich aber den Font dem Label anstelle MyFont zu, gibt es kein SIGSEGV.

Code: Alles auswählen

type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    FontBtn: TButton;
    FontDialog1: TFontDialog;
    Label1: TLabel;
    procedure FontBtnClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    MyFont: TFont;
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FontBtnClick(Sender: TObject);
begin
  if FontDialog1.Execute then begin
    MyFont := FontDialog1.Font;
//    Label1.Font := FontDialog1.Font;
  end;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  MyFont := TFont.Create;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
  MyFont.Free;
end;
 
end.  
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: TFont, TFontDialg gibt SIGSEGV

Beitrag von theo »

Das kann nicht gehen.
Du createst einen Font und weist der FontVariablen (MyFont) nacher den Zeiger des FontDialog.Font zu, womit du keinen Zugriff auf deinen originalen Font mehr hast.
Dafür destroyest du den FontDialog.Font.

Mach es so:

Code: Alles auswählen

 
  if FontDialog1.Execute then begin
    MyFont.Assign(FontDialog1.Font);   
So kopierst du die Eigenschaften.

Mathias
Beiträge: 6918
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: TFont, TFontDialg gibt SIGSEGV

Beitrag von Mathias »

Danke, jetzt gehts.

Dann muss ich es bei TBitmap wohl auch so machen ?
Nur hier hat es mit der Zeigerzuweisung funktionert, obwohl ich FontBitmap und Font mit Free freigegeben habe.

Code: Alles auswählen

 
  public
    Font: TFont;
..........
var
  FontBitmap: TBitmap;
  sizex, sizey: integer;
  i: integer;
 
begin
  FontBitmap := TBitmap.Create;
 
//  FontBitmap.Canvas.Font := Font;
  FontBitmap.Canvas.Font.Assign(Font);
 
  FontBitmap.Canvas.Brush.Color := BKColor  ;
 
  sizex := FontBitmap.Canvas.TextWidth('1');
  sizey := FontBitmap.Canvas.TextHeight('1');
 
  FontBitmap.Width := sizex * 10;
  FontBitmap.Height := sizey;
 
  for i := 0 to 9 do begin
    FontBitmap.Canvas.TextOut(i * sizex, 0, IntToStr(i));
  end;
 
  TexturBuffer.LoadTextures(FontBitmap);
  FontBitmap.Free;  
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 5153
Registriert: Fr 8. Apr 2011, 09:01

Re: TFont, TFontDialg gibt SIGSEGV

Beitrag von wp_xyz »

Schau dir mal den Quellcode von TCanvas an:

Code: Alles auswählen

type
  TCanvas = class(...)
  private
    FLazFont: TFont;
    procedure SetLazFont(Value: TFont);
   ...
  published
    property Font: TFont read FLazFont write SetLazFont;
    ...
  end;
 
procedure TCanvas.SetLazFont(Value : TFont);
begin
  FLazFont.Assign(Value);
end;
Font ist ein Property des Canvas. Wenn du die Zuweisung "Canvas.Font := IrgendeinFont" in deinen Code schreibst, wird in der Methode "SetLazFont" eigentlich "Canvas.Font.Assign(irgendeinFont)" aufgerufen. In der umgekehrten Richtung dagegen wird nur der Pointer auf die interne Variable FLazFont zugewiesen, hier hättest du das Problem wieder.

Antworten