Ошибки программы при попытке изменить формы

Сначала я создал форму, которая будет показывать настройки. Затем я создал окно входа, которое будет загружать пароль из INI-файла. Я изначально думал, что это ошибка при загрузке INI-файла. Хотя я выделил его, когда я загружаю форму настроек. Вот код для всех них.

Код для экрана настроек:

    unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, inifiles;

type

  TForm1 = class(TForm)
    SaveButton: TButton;
    AEditA: TEdit;
    AEditB: TEdit;
    SEditB: TEdit;
    PEditB: TEdit;
    PLabelA: TLabel;
    SLabelA: TLabel;
    ALabelA: TLabel;
    PEditA: TEdit;
    SEditA: TEdit;
    ExitButton: TButton;
    Settings: TLabel;
    ALabelB: TLabel;
    SLabelB: TLabel;
    PLabelB: TLabel;
    AReserveLabel: TLabel;
    BReserveLabel: TLabel;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label8: TLabel;
    Label7: TLabel;
    procedure SaveButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ExitButtonClick(Sender: TObject);
    procedure AEditAKeyPress(Sender: TObject; var Key: Char);
    procedure AEditBKeyPress(Sender: TObject; var Key: Char);
    procedure SEditAKeyPress(Sender: TObject; var Key: Char);
    procedure SEditBKeyPress(Sender: TObject; var Key: Char);
    procedure PEditAKeyPress(Sender: TObject; var Key: Char);
    procedure PEditBKeyPress(Sender: TObject; var Key: Char);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  IniFile : TIniFile;
  appINI : TIniFile;
  APriceA : String;
  SPriceA : String;
  PPriceA : String;
  APriceB : String;
  SPriceB : String;
  PPriceB : String;

implementation


{$R *.DFM}

procedure TForm1.SaveButtonClick(Sender: TObject);
//Save Button
 begin
  appINI := TIniFile.Create(ChangeFileExt(Application.ExeName,'.ini'));
  APriceA := (AEditA.Text);
  SPriceA := (SEditA.Text);
  PPriceA := (PEditA.Text);
  APriceB := (AEditB.Text);
  SPriceB := (SEditB.Text);
  PPriceB := (PEditB.Text);
  appINI.WriteString('PricesA','Adult',APriceA);
  appINI.WriteString('PricesA','Student',SPriceA);
  appINI.WriteString('PricesA','Pensioner',PPriceA);
  appINI.WriteString('PricesB','Adult',APriceB);
  appINI.WriteString('PricesB','Student',SPriceB);
  appINI.WriteString('PricesB','Pensioner',PPriceB);
  appINI.Free;
  ShowMessage('Settings Saved Successfully!');
 end;

procedure TForm1.FormCreate(Sender: TObject);
//Displays values as the form is created
begin
{ appINI := TIniFile.Create(ChangeFileExt(Application.ExeName,'.ini'));
APriceA := appINI.ReadString('PricesA','Adult','');
SPriceA := appINI.ReadString('PricesA','Student','');
PPriceA := appINI.ReadString('PricesA','Pensioner','');
APriceB := appINI.ReadString('PricesB','Adult','');
SPriceB := appINI.ReadString('PricesB','Student','');
PPriceB := appINI.ReadString('PricesB','Pensioner','');
appINI.Free;
AEditA.Text := (APriceA);
SEditA.Text := (SPriceA);
PEditA.Text := (PPriceA);
AEditB.Text := (APriceB);
SEditB.Text := (SPriceB);
PEditB.Text := (PPriceB);}
end;

procedure TForm1.ExitButtonClick(Sender: TObject);
//Exit Button
begin
Close;
end;

procedure TForm1.AEditAKeyPress(Sender: TObject; var Key: Char);
var s:string;
begin
  s := ('1234567890.'#8); //Add chars you want to allow
  if pos(key,s) =0 then begin
    Key:=#0;
    showmessage('Only Numbers are allowed. Include cents!');
  end;
end;

procedure TForm1.AEditBKeyPress(Sender: TObject; var Key: Char);
var s:string;
begin
  s := ('1234567890.'#8); //Add chars you want to allow
  if pos(key,s) =0 then begin
    Key:=#0;
    showmessage('Only Numbers are allowed. Include cents!');
  end;
end;

procedure TForm1.SEditAKeyPress(Sender: TObject; var Key: Char);
var s:string;
begin
  s := ('1234567890.'#8); //Add chars you want to allow
  if pos(key,s) =0 then begin
    Key:=#0;
    showmessage('Only Numbers are allowed. Include cents!');
  end;
end;

procedure TForm1.SEditBKeyPress(Sender: TObject; var Key: Char);
var s:string;
begin
  s := ('1234567890.'#8); //Add chars you want to allow
  if pos(key,s) =0 then begin
    Key:=#0;
    showmessage('Only Numbers are allowed. Include cents!');
  end;
end;

procedure TForm1.PEditAKeyPress(Sender: TObject; var Key: Char);
var s:string;
begin
  s := ('1234567890.'#8); //Add chars you want to allow
  if pos(key,s) =0 then begin
    Key:=#0;
    showmessage('Only Numbers are allowed. Include cents!');
  end;
end;

procedure TForm1.PEditBKeyPress(Sender: TObject; var Key: Char);
var s:string;
begin
  s := ('1234567890.'#8); //Add chars you want to allow
  if pos(key,s) =0 then begin
    Key:=#0;
    showmessage('Only Numbers are allowed. Include cents!');
  end;
end;
//End of Settings
end.

Код для формы входа:

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Mask, inifiles, Unit1;

type
  TForm2 = class(TForm)
    PassEdit: TMaskEdit;
    LoginButton: TButton;
    PassLabel: TLabel;
    InvisiButton: TButton;
    procedure PassEditClick(Sender: TObject);
    procedure LoginButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;
  IniFile : TIniFile;
  appINI : TIniFile;
  Password : string;

implementation



{$R *.DFM}

procedure TForm2.PassEditClick(Sender: TObject);
begin
PassEdit.Text := '';
end;

procedure TForm2.LoginButtonClick(Sender: TObject);
begin
//if Password = PassEdit.Text then begin
Form2.Hide;
showmessage('test');
Form1.Show;
end;
//end;
procedure TForm2.FormCreate(Sender: TObject);
begin
appINI := TIniFile.Create(ChangeFileExt(Application.ExeName,'.ini'));
Password := appINI.ReadString('Login','Password','');
ShowMessage(Password);
appINI.Free;
end;

end.

Это проект:

program Project1;

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


{$R *.RES}

begin
  Application.Initialize;
  //Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.

1 ответ

Вы закомментировали строку кода в .dpr file that createsForm1`:

  //Application.CreateForm(TForm1, Form1);

Но вы получаете доступ к этой несозданной форме в Unit1:

procedure TForm2.LoginButtonClick(Sender: TObject);
begin
//if Password = PassEdit.Text then begin
Form2.Hide;
showmessage('test');
Form1.Show;        // <-- Accessing uncreated form here
end;

Раскомментируйте строку в файле проекта, чтобы он был создан. Обратите внимание, что первая форма, созданная с Application.CreateForm становится главной формой вашего приложения, и когда эта форма закрывается, ваше приложение закрывается.

У вас также есть еще один серьезный недостаток в вашем коде. Вы никогда не должны ссылаться на саму форму по имени из одного из ее собственных методов, как вы делаете здесь изнутри TForm2.LoginButtonClick:

    Form2.Hide;

Это означает, что если вы когда-нибудь переименуете форму, она не будет скомпилирована, а если вы создадите более одной TForm2ваш код будет иметь неверный доступ или вызовет нарушения прав доступа к несозданной форме (например, проблема, с которой вы столкнулись сейчас). Вы должны либо просто использовать метод формы напрямую, например, Hide;' from the method, or useSelf.Hide;`для ссылки на экземпляр, в данный момент выполняющий метод.

(Для справки в будущем: если у вас возникла проблема, полезно объяснить, что это за проблема, когда вы просите о помощи в ее решении. "Программные ошибки", в которых нет другой информации об ошибке, сами по себе бессмысленны. При вводе "error" следующее, что вы должны добавить, это точная ошибка, которая у вас есть, включая точное сообщение об ошибке, включая любую информацию об адресе. Мы не можем видеть ваш экран с того места, где мы находимся, поэтому у нас есть только та информация, которую вы нам предоставляете, чтобы перейти помогая вам.)

Другие вопросы по тегам