I have a base form that I am trying to use for multiple forms on screen at once. I thought I set up inheritance correctly but when I create 2 forms, only the last one created shows up on the screen. I also can't get the title string to actually change when passed in with the constructor.
Here is my ancestor form:
unit BasePanel;
interface
uses
Windows,
Messages,
SysUtils,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
OvcBase,
StdCtrls,
ExtCtrls,
MySBox,
AdvGroupBox,
AdvOfficeImage,
EnJpgGr,
BorderPanel,
AdvPanel,
Grids,
AdvObj,
BaseGrid,
AdvGrid,
AdvUtil;
type
TBasePanelForm = class(TForm)
MainPanel: TAdvPanel;
BaseTimer: TTimer;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure SavePosition;
procedure SetTimerInterval(Interval: Cardinal);
constructor CreatePanel(Name:String; Title:String; TimerEnabled: Boolean);
end;
var
BasePanelForm: TBasePanelForm;
PanelName : String;
BaseTimerEnabled: Boolean;
PanelTitle:String;
implementation
{$R *.dfm}
constructor TBasePanelForm.CreatePanel(Name: String; Title:String; TimerEnabled: Boolean);
begin
inherited Create(application);
PanelName := Name;
if Title = '' then
Title := PanelName;
PanelTitle := Title;
BaseTimerEnabled := TimerEnabled;
end;
procedure TBasePanelForm.SetTimerInterval(Interval: Cardinal);
begin
BaseTimer.Interval := Interval;
end;
procedure TBasePanelForm.FormCreate(Sender: TObject);
begin
self.MainPanel.Text := '<img src="idx:1"> ' + PanelTitle;
BaseTimer.Enabled := BaseTimerEnabled;
MainPanel.OptimizePaint := True;
MainPanel.DoubleBuffered := True;
end;
procedure TBasePanelForm.SavePosition;
begin
//Save the postions to ini
BaseTimer.Interval := 1;
end;
end.
Here is one of the forms that inherit it:
unit WeatherPanel;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, BasePanel, Vcl.ExtCtrls, AdvPanel,
AdvCustomControl, AdvWebBrowser;
type
TWeatherPanelForm = class(TBasePanelForm)
WebBrowser: TAdvWebBrowser;
constructor CreatePanel(url_string:String);
procedure BaseTimerTimer(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
end;
var
WeatherPanelForm: TWeatherPanelForm;
URL:String;
implementation
{$R *.dfm}
constructor TWeatherPanelForm.CreatePanel(url_string:String);
begin
inherited CreatePanel('weather','Weather', True);
URL := url_string;
end;
procedure TWeatherPanelForm.FormCreate(Sender: TObject);
begin
inherited;
WebBrowser.Navigate(URL);
end;
end.
Here is how I create them:
TextPanelForm := TTextPanelForm.CreatePanel;
TextPanelForm.Parent := MainForm;
TextPanelForm.Top := 0;
TextPanelForm.Left := 0;
TextPanelForm.Visible := true;
TextPanelForm.Show;
WeatherPanelForm := TWeatherPanelForm.CreatePanel('url-here');
WeatherPanelForm.Parent := MainForm;
WeatherPanelForm.Visible := true;
WeatherPanelForm.Show;
WeatherPanelForm.Top := 300;
WeatherPanelForm.Left := 500;
I tried setting up form inheritance. File->New->Other->Inherited. TextPanelForm and WeatherPanelForm both inherit the basepanelform
I was expecting to be able to instantiate separate instances of the base form. Like setting the title of the panel when I create each form.
Only the weather panel is shown, and the title label I set does not change from what's in the BasePanel by default.
It seems like it is acting like it uses only 1 single instance of the BasePanel and if I change a property in the BasePanel instance at runtime, it doesn't carry out what is shown on screen.
What am I doing wrong?
I copied your code pretty much as you presented it and it worked fine. I ended up with two forms contained in the main form. You can either create an inherited form or simply use [File | New | VCL Form] to create the form and manually change the class statement from TForm to TBaseForm (and include BasePanel in the uses clause). Either way is fine.
Moving the global variables into the class will avoid any conflict when creating multiple forms. This also includes the "URL" variable in your Weather form.
As for instantiation, as you are creating these forms manually, you will need to go into [Project | Options] and select "Forms" from the TreeView. Move the Weather and Text forms from "Auto-create Forms" to "Available forms". Otherwise you'll end up with two of each. (Only one will be visible because the auto-created form does not call the CreatePanel constructor.)
Base Panel
Weather Panel
Main Form
Note that I have programatically created TextPanelForm and created WeatherPanelForm in the IDE. Both methods are valid depending on your requirements.