Font doesn't change after creating a dynamic tab

Dear Experts,

In my example I have a procedure called NewTab that creates
dynamicly Pagecontrol Pages with a richedit (align = alClient) on it.
This procedure will be executed at creation (so the application starts
with at least 1 page) and with the menu-item called New Page
(to give the user the ability to create more pages).

I have made another form called SettingsDlg with a combox and
a spinedit on it for choosing a fontname and size that will change the
text of all the richedits that are created on the main form after pressing the
OK-button.

All that works fine, accept for one thing:

f.e: when there are 3 pages created with their richedit's, and in all 3 of them
is some text. Then I open de SettingsDlg to choose another fontname and size.
for example Comic Sans MS+12. After pressing the OK-button the text of all 3 of
them will be changed, but then I create a new page and when I put some text in
it, its not the textname and size that I have choosen. In other words: the procedure
NewTab have to call for the procedure "SettingsDlg.ApplyDefaultSettings" also. But
When I do that I get an Acces-violation.

Who knows the answer and is willing to help me?
I have put the code in the code-section.

Peter

unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, DB, ADODB, ComCtrls, StdCtrls, ExtCtrls, DBCtrls;

type
  TMainForm = class(TForm)
    PageControl1: TPageControl;
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Exit1: TMenuItem;
    Settings1: TMenuItem;
    Edit1: TMenuItem;
    Insert1: TMenuItem;
    NewPage1: TMenuItem;
    procedure FormShow(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure NewPage1Click(Sender: TObject);
    procedure Settings1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure NewTab;
  end;

var
  MainForm: TMainForm;

implementation

uses Settings;

{$R *.dfm}

procedure TMainForm.FormCreate(Sender: TObject);
begin
  NewTab;
end;
(*---------------------------------------------------*)
procedure TMainForm.FormShow(Sender: TObject);
begin
  SettingsDlg.ApplyDefaultSettings;
end;
(*---------------------------------------------------*)
procedure TMainForm.NewPage1Click(Sender: TObject);
begin
  NewTab;
end;
(*---------------------------------------------------*)
procedure TMainForm.NewTab;
var
  aRE: TRichEdit;
  tabSheet: TTabSheet;
begin
  tabSheet := TTabSheet.Create(PageControl1);
  tabSheet.PageControl := PageControl1;
  tabSheet.Name := 'TabSheet' + IntToStr(tabSheet.tabindex+1);
  tabSheet.caption := 'Page' + '(' + IntToStr(tabSheet.tabindex+1) + ')';
  aRE := TRichEdit.Create(tabSheet);
  aRE.Parent := tabSheet;
  aRe.Name := 'RichEdit' + IntToStr(tabSheet.tabindex+1);    
  aRE.Align := alClient;
  aRE.ParentFont := False;
  aRE.HideSelection := False;
  aRE.ScrollBars := ssVertical;
  aRE.Visible := True;
  PageControl1.ActivePage := tabSheet;
end;
(*---------------------------------------------------*)
procedure TMainForm.Settings1Click(Sender: TObject);
begin
  SettingsDlg.ShowModal;
end;
(*---------------------------------------------------*)
end.

unit Settings;

interface

uses Windows, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls,
  Buttons, ComCtrls, ExtCtrls, Spin, IniFiles, DBCtrls;


type
  TSettingsDlg = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    OKBtn: TButton;
    CancelBtn: TButton;
    HelpBtn: TButton;
    GroupBox1: TGroupBox;
    lblFontName: TLabel;
    lblFontSize: TLabel;
    cbFontName: TComboBox;
    edtFontSize: TSpinEdit;
    procedure OKBtnClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    SettingsFile: string; 
    procedure GetFontNames;
    procedure LoadSettings;
    procedure SaveSettings;
  public
    { Public declarations }
    procedure ApplyDefaultSettings;
  end;

var
  SettingsDlg: TSettingsDlg;

implementation

uses Main;

{$R *.dfm}

function EnumFontsProc(var LogFont: TLogFont; var TextMetric: TTextMetric;
  FontType: Integer; Data: Pointer): Integer; stdcall;
begin
  TStrings(Data).Add(LogFont.lfFaceName);
  Result := 1;
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.ApplyDefaultSettings;
var
 z, i: Integer;
begin
 with MainForm.PageControl1 do
  for z := 0 to PageCount -1 do
   for i := 0 to Pages[z].ControlCount - 1 do
    if Pages[z].Controls[i] is TRichEdit Then
     with (Pages[z].Controls[i] As TRichEdit).DefAttributes do
      begin
       Name := cbFontName.Items[cbFontName.ItemIndex];
       Size := StrToInt(edtFontSize.Text);
      end;
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.FormCreate(Sender: TObject);
begin
 GetFontNames;
 SettingsFile := ChangeFileExt(Application.ExeName, '.ini');
 LoadSettings;
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.FormDestroy(Sender: TObject);
begin
 SaveSettings;
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.GetFontNames;
var
  DC: HDC;
begin
  DC := GetDC(0);
  EnumFonts(DC, nil, @EnumFontsProc, Pointer(cbFontName.Items));
  ReleaseDC(0, DC);
  cbFontName.Sorted := True;
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.LoadSettings;
var ini: TIniFile; 
begin 
  ini := TIniFile.Create(SettingsFile); 
  try 
   cbFontName.ItemIndex  := cbFontName.Items.IndexOf(ini.ReadString('Font', 'FaceName', Font.Name)); 
   edtFontSize.Value := ini.ReadInteger('Font', 'PointSize', Font.Size); 
  finally 
    FreeAndNil(ini) 
  end; 
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.OKBtnClick(Sender: TObject);
begin
 ApplyDefaultSettings;
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.SaveSettings;
var ini: TIniFile; 
begin 
  ini := TIniFile.Create(SettingsFile); 
  try 
    ini.WriteString('Font', 'FaceName', cbFontName.Items[cbFontName.ItemIndex]); 
    ini.WriteInteger('Font', 'PointSize', edtFontSize.Value); 
  finally 
    FreeAndNil(ini) 
  end; 
end;
(*---------------------------------------------------*)
end.

Open in new window

LVL 1
peterkiersAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Emmanuel PASQUIERFreelance Project ManagerCommented:
You are calling NewTab when you create your main form, which in turns try to call SettingsDlg method, but this secondary form is not yet created.
So in NewTab you have to test this before and not call it if SettingsDlg is not yet created. Then when you create your SettingsDlg form, after loading the settings, you apply the Default settings to all tabs' richedit.

To optimize a bit, when creating a new tab, I don't call ApplyDefaultSettings which will scan all tabs and controls in it, but a simple version of it that I now call ApplyDefaultSettingsToRE (used by ApplyDefaultSettings) that only target one RE.
procedure TSettingsDlg.ApplyDefaultSettingsToRE(RE:TRichEdit);
begin
 with RE.DefAttributes do
  begin
   Name := cbFontName.Items[cbFontName.ItemIndex];
   Size := StrToInt(edtFontSize.Text);
  end;
end;

procedure TSettingsDlg.ApplyDefaultSettings;
var
 z, i: Integer;
begin
 with MainForm.PageControl1 do
  for z := 0 to PageCount -1 do
   for i := 0 to Pages[z].ControlCount - 1 do
    if Pages[z].Controls[i] is TRichEdit Then
     ApplyDefaultSettingsToRE(Pages[z].Controls[i] As TRichEdit);
end;

procedure TSettingsDlg.LoadSettings;
var ini: TIniFile; 
begin 
  ini := TIniFile.Create(SettingsFile); 
  try 
   cbFontName.ItemIndex  := cbFontName.Items.IndexOf(ini.ReadString('Font', 'FaceName', Font.Name)); 
   edtFontSize.Value := ini.ReadInteger('Font', 'PointSize', Font.Size); 
  finally 
    FreeAndNil(ini) 
  end; 
 ApplyDefaultSettings;
end;

procedure TMainForm.NewTab;
var
  aRE: TRichEdit;
  tabSheet: TTabSheet;
begin
  tabSheet := TTabSheet.Create(PageControl1);
  tabSheet.PageControl := PageControl1;
  tabSheet.Name := 'TabSheet' + IntToStr(tabSheet.tabindex+1);
  tabSheet.caption := 'Page' + '(' + IntToStr(tabSheet.tabindex+1) + ')';
  aRE := TRichEdit.Create(tabSheet);
  aRE.Parent := tabSheet;
  aRe.Name := 'RichEdit' + IntToStr(tabSheet.tabindex+1);    
  aRE.Align := alClient;
  aRE.ParentFont := False;
  aRE.HideSelection := False;
  aRE.ScrollBars := ssVertical;
  aRE.Visible := True;
  PageControl1.ActivePage := tabSheet;
  if Assigned(SettingsDlg) Then SettingsDlg.ApplyDefaultSettingsToRE(aRE);
end;

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
peterkiersAuthor Commented:
Thanks it works great. 500 points are comming to you.

Greetings,

Peter Kiers
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.