Mega Search
23.2 Million


Sign Up

Make a donation  
How to access the public member in function? [Edit]  
News Group: embarcadero.public.delphi.firemonkey

I want to create a simple class .

But it is hard for me in delphi~

I got a error message "First chance exception at $000000000040FF2C. Exception class $C0000005 with message 'c0000005 ACCESS_VIOLATION'. Process MySew.exe (6068)",

 when i run my program. How to fix it?



unit FileFormat;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes,
  System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs;

type
  clsZHSFile = class(TForm)

  private
    // iRecordStart: integer;
    // TBinaryReader: reader;
    // FileLength: long;

  public
    myMemo: string;
    Constructor Create();
    function ReadFile(FileName: String): integer;
    function ReadFile_V1_1(reader: TBinaryReader): integer;
  published
  end;

implementation

{ clsZHSFile }
constructor clsZHSFile.Create;
begin
  // self.myMemo := '';
end;

function clsZHSFile.ReadFile_V1_1(reader: TBinaryReader): integer;
begin
  myMemo := 'Q';//<----------------------------------------------------------------------------How to access the public string in a function
  // Memo1.Text := MyClass.Memo;
  // SetLength(FileID, 5);
  // FileID := reader.ReadBytes(5);
  // Memo1.Lines.Add(TEncoding.UTF8.GetString(FileID));
  // // 版本
  // FileID := reader.ReadBytes(2);
  // SetLength(FileID, 2);
  // Memo1.Lines.Add(TEncoding.UTF8.GetString(FileID));
  Result := 1;
end;

function clsZHSFile.ReadFile(FileName: String): integer;
var
  Stream: TFileStream;
  reader: TBinaryReader;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead);
  reader := TBinaryReader.Create(Stream, TEncoding.Default, false);
  Result := ReadFile_V1_1(reader);
  reader.Free;
  Stream.Free;
end;

{ clsZHSFile }
end.

//%%%%%%%%%%%%%%%%%%%%
//%%%% MAIN CODE %%%%%%%
//%%%%%%%%%%%%%%%%%%%%

unit MySew_u;

interface

uses
  System.IOUtils, System.SysUtils, System.Types, System.UITypes, System.Classes,
  System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FileFormat,
  FMX.StdCtrls, FMX.Layouts, FMX.Memo;

type
  TForm4 = class(TForm)
    btnLoadFile: TButton;
    lblFolder: TLabel;
    lblLocation: TLabel;
    Memo1: TMemo;
    procedure btnLoadFileClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

{$R *.fmx}
{$R *.Windows.fmx MSWINDOWS}
{$R *.SmXhdpiPh.fmx ANDROID}
{$R *.iPhone.fmx IOS}

procedure TForm4.btnLoadFileClick(Sender: TObject);
var
  reader: TBinaryReader;
  MyClass: clsZHSFile;
  i: integer;
begin
  lblFolder.Text := TPath.GetDocumentsPath(); // System.IOUtils.
  lblLocation.Text := TPath.Combine(lblFolder.Text, 'G1_02_13.zhs');
  MyClass := clsZHSFile.Create;
  i := MyClass.ReadFile(lblLocation.Text);
  // Memo1.Text := MyClass.myMemo;
end;

end.
Edited by: chen wei-lun on Jan 18, 2015 5:11 PM

Edited by: chen wei-lun on Jan 19, 2015 8:53 PM

Edited by: chen wei-lun on Jan 19, 2015 8:59 PM

Edited by: chen wei-lun on Jan 19, 2015 9:03 PM
Update my code

Vote for best question.
Score: 0  # Vote:  0
Date Posted: 19-Jan-2015, at 9:03 PM EST
From: chen wei-lun
 
Re: How to access the public member in function? [Edit] [Edi  
News Group: embarcadero.public.delphi.firemonkey
chen wrote:

> It work!
> 
> but there are new error message "Resource clsZHSFile not
> found."<------------------------------I don't know why?

As I said earlier, your clsZHSFile class derives from TForm but has no DFM. 
 That is what the error is complaining about.  If you really want the class 
to derive from TForm without a DFM, you need to use the TForm.CreateNew() 
constructor instead, which bypasses DFM streaming.

> In the clsZHSFile class, change my code to those:
> 
> {code}clsZHSFile = class {code}
> {code}  constructor Create();{code}
> {code}constructor clsZHSFile.Create();

That is fine.  That will get rid of the resource error, and the TForm dependancy.

> clsZHSFile is a class for saving ZHS format.

Then there is no reason to derive it from TForm.

> But I don't know what the different between QT5.4 and FMX.

Everything.  There are completely different frameworks, nothing in common 
other than they are both designed to be cross-platform.

-- 
Remy Lebeau (TeamB)

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 20-Jan-2015, at 8:52 PM EST
From: Remy Lebeau (TeamB)
 
Re: How to access the public member in function? [Edit] [Edi  
News Group: embarcadero.public.delphi.firemonkey
It work!

but there are new error message "Resource clsZHSFile not found."<------------------------------I don't know why?

Thanks for your reminder. I check my code about "constructor ,TComponent,...".

 In the clsZHSFile class, change my code to those:
 
 {code}clsZHSFile = class {code}
 {code}  constructor Create();{code}
 {code}constructor clsZHSFile.Create();
begin
  inherited;
  // self.myMemo := '';
end; {code}
 {code} MyClass := clsZHSFile.Create(); {code}

It work!   ^___^ Thanks~

> That being said, why are you deriving clsZHSFile from TForm in the first 
> place, if you are not going to Show() it to the user?  It does not appear 
> to have a DFM attached to it, either.

clsZHSFile is a class for saving ZHS format.
I have the other class like this. ex. clsAAAFile,clsBBBFile.....
Hence, I want to deriving clsZHSFile from the first place for managing my code easily.


Edited by: chen wei-lun on Jan 20, 2015 7:50 PM

Edited by: chen wei-lun on Jan 20, 2015 8:51 PM

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 20-Jan-2015, at 8:52 PM EST
From: chen wei-lun
 
Re: How to access the public member in function? [Edit]  
News Group: embarcadero.public.delphi.firemonkey
chen write:

> I want to create a simple class .
> 
> But it is hard for me in delphi~

The only mistake I see in this code is that you are not overriding the existing 
TForm constructor.  In the clsZHSFile class, change your constructor to this 
instead:

{code}
constructor Create(AOwner: TComponent); override;
{code}

And make sure the implementation calls the inherited constructor:

{code}
constructor clsZHSFile.Create(AOwner: TComponent);
begin
  inherited;
  // self.myMemo := '';
end;
{code}

Then call this constructor like this in your other Form:

{code}
procedure TForm4.btnLoadFileClick(Sender: TObject);
var
  ...
  MyClass: clsZHSFile;
  ...
begin
  ...
  MyClass := clsZHSFile.Create(nil);
  ...
end;
{code}

That being said, why are you deriving clsZHSFile from TForm in the first 
place, if you are not going to Show() it to the user?  It does not appear 
to have a DFM attached to it, either.

-- 
Remy Lebeau (TeamB)

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 20-Jan-2015, at 12:05 PM EST
From: Remy Lebeau (TeamB)
 
Re: How to access the public member in function? [Edit]  
News Group: embarcadero.public.delphi.firemonkey
chen wrote:

> should I add the constructor in my code?

It is not a matter of ADDING a constructor.  Are you CALLING a constructor 
before USING the component?  Again, please show the code that is actually 
USING the component.

> and it  looks like the below code :
>
> constructor clsZHSFile.Create;
> begin
> self.myMemo := '';
> end;
>
> But it still has an error~~~

Aside from a lack of call to the inherited constructor, there is nothing 
in that code snippet that would cause an AV, unless myMemo is not being initialized 
to nil correctly before the assignment is performed.

-- 
Remy Lebeau (TeamB)

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 19-Jan-2015, at 1:04 PM EST
From: Remy Lebeau (TeamB)
 
Re: How to access the public member in function? [Edit]  
News Group: embarcadero.public.delphi.firemonkey
yep, you got me.( I know why now)

should I add the constructor in my code?

I add the code "Constructor Create();" in my code ,

and it  looks like the below code :
   constructor clsZHSFile.Create;
   begin
     self.myMemo := '';
   end;

But it still has an error~~~

the error message:
First chance exception at $0000000000A56818. Exception class $C0000005 with message 'c0000005 ACCESS_VIOLATION'. Process MySew.exe (2972)

> {quote:title=Remy Lebeau (TeamB) wrote:}{quote}
> chen wrote:
> 
> > I got a error message "First chance exception at $000000000040FF2C.
> > Exception class $C0000005 with message 'c0000005 ACCESS_VIOLATION'.
> 
> That suggests that you likely did not create an object instance of clsZHSFile 
> before trying to access its members.  You did not show the code that is actually 
> using clsZHSFile.ReadFile(), but you probably did something like this:
> 
> {code}
> var
>   f: clsZHSFile;
> begin
>   f.ReadFile(filename);
>   ...
> {code}
> 
> When you need to do thing instead:
> 
> {code}
> var
>   f: clsZHSFile;
> begin
>   f := clsZHSFile.Create; // <-- add this!
>   f.ReadFile(filename);
>   ...
> {code}
> 
> BTW, you need to add some try/finally blocks to your ReadFile() method to 
> avoid memory leaks if an error occurs on a non-mobile platform:
> 
> {code}
> function clsZHSFile.ReadFile(FileName: String): integer;
> var
>   Stream: TFileStream;
>   reader: TBinaryReader;
> begin
>   Stream := TFileStream.Create(FileName, fmOpenRead);
>   try
>     reader := TBinaryReader.Create(Stream, TEncoding.Default, false);
>     try
>       Result := ReadFile_V1_1(reader);
>     finally
>       reader.Free;
>     end;
>   finally
>     Stream.Free;
>   end;
> end;
> {code}
> 
> -- 
> Remy Lebeau (TeamB)

Edited by: chen wei-lun on Jan 18, 2015 8:01 PM

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 18-Jan-2015, at 8:01 PM EST
From: chen wei-lun
 
Re: How to access the public member in function? [Edit]  
News Group: embarcadero.public.delphi.firemonkey
chen wrote:

> I got a error message "First chance exception at $000000000040FF2C.
> Exception class $C0000005 with message 'c0000005 ACCESS_VIOLATION'.

That suggests that you likely did not create an object instance of clsZHSFile 
before trying to access its members.  You did not show the code that is actually 
using clsZHSFile.ReadFile(), but you probably did something like this:

{code}
var
  f: clsZHSFile;
begin
  f.ReadFile(filename);
  ...
{code}

When you need to do thing instead:

{code}
var
  f: clsZHSFile;
begin
  f := clsZHSFile.Create; // <-- add this!
  f.ReadFile(filename);
  ...
{code}

BTW, you need to add some try/finally blocks to your ReadFile() method to 
avoid memory leaks if an error occurs on a non-mobile platform:

{code}
function clsZHSFile.ReadFile(FileName: String): integer;
var
  Stream: TFileStream;
  reader: TBinaryReader;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead);
  try
    reader := TBinaryReader.Create(Stream, TEncoding.Default, false);
    try
      Result := ReadFile_V1_1(reader);
    finally
      reader.Free;
    end;
  finally
    Stream.Free;
  end;
end;
{code}

-- 
Remy Lebeau (TeamB)

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 18-Jan-2015, at 5:44 PM EST
From: Remy Lebeau (TeamB)