Recent

Author Topic: source editor  (Read 6088 times)

hamza

  • Jr. Member
  • **
  • Posts: 52
source editor
« on: April 30, 2015, 12:01:51 pm »
hi

I am looking to find an explanation for Lazarus source editor (the first screen after making new project)
because I need to know ,where should i put variables to make glopal var  and whre to put the functions...etc
so,where I can find that??
thank you

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: source editor
« Reply #1 on: April 30, 2015, 12:23:36 pm »
There are two different cases.

If your project is a console project (New-> Simple Program) then the source editor opens the project's .lpr file (project1.lpr). You see:
Code: [Select]
program project1;

begin
end.

You have considerable freedom about where and in what order you place global variables and functions, but a typical 'template' would look like this:

Code: [Select]
program project1;

function Sum(aNum1, aNum2: integer): int64;
begin
  Result:=aNum1 + aNum2;
end;

var
  n1, n2: integer; // global variables go here

begin
  n1:=374;
  n2:=56;
  Writeln('Total of ',n1,' + ',n2,' is ', Sum(n1, n2));
end.

If you are developing a GUI project (New->Application) then you are not shown the project's .lpr file, but the code for the first form unit:

Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;

type
  TForm1 = class(TForm)
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1; // this is a global variable created by Lazarus. You can add others here...

implementation

{$R *.lfm}

end.


You add global variables at the point indicated above, and global function headers would go in that region as well. The implementation of such functions is placed lower in the source code after the "implementation" keyword.
Functions that you want to be methods of TForm1 would be placed where the source editor has put the comments {private declarations} and {public declarations}.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: source editor
« Reply #2 on: April 30, 2015, 12:28:28 pm »
there are multiple types of projects you need to be a bit more specific. In general anything declared in the interface part of a unit will be accessible by any code that uses that unit and is considered global any procedure or function declaration (aka only the procedure xxxx(yyy:zzzz); part) that is in the interface unit can be called and used from any code that uses that unit. You can not write code in the interface part you need to write the code in the implementation part of a unit. EG.
Code: [Select]

Unit MyData;
interface

type
  Ulong = Cardinal;

var
  MyExceptionalVariable : Ulong; //global to any one that uses this unit.

procedure Inc(var MyLong:Ulong);  //the following procedures can be used outside this unit.
procedure Dev(Var MyLong:ULong);

implementation
var
  MyLocalVar:String; // this is local to the unit can be access by any pice of code in the unit.

function Add(const aBase:Ulong; aNo:integer);//this function can not be used outside this unit.
begin
  Result := aBase + aNo;
end;

procedure Inc(var MyLong:Ulong);
begin
  MyLong := add(MyLong, 1);
end;

procedure Dec(var MyLong : Ulong);
begin
  MyLong := add(MyLong, -1);
end;

end.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

hamza

  • Jr. Member
  • **
  • Posts: 52
Re: source editor
« Reply #3 on: April 30, 2015, 01:46:59 pm »
 howardpc and taazz, thank you for help

I will be more specific.
I Am trying to add new function to my project(developing a GUI project (New->Application) )
the original place of the vairables and labeles is as follow

type

  { TForm1 }

  TForm1 = class(TForm)
    Label1: TLabel;

  private
    { private declarations }

  public
    { public declarations }

  end;               

var
  Form1: TForm1;
    xxx, : SmallInt  ;/// I understand from your reply this variable will be glopal var(good)
implementation

{$R *.lfm}


function my_function : integer ;
  begin
do_something
Label1: used inside function
  end;

but when I make run for the project , the messeage will appeare to dispaly that "identifer of lable1 is not found".
also when I put(change location) the lable as below and make run ,the project will succseccfully built but when I Press the button in my project to call this function ,a new error message apeeared
the message is "PROJECT RAISED EXCPTION CLASS EXTERNAL SIGSEGV"
var
  Form1: TForm1;
    xxx, : SmallInt  ;
Label1: TLabel;

implementation

{$R *.lfm}

function my_function : integer ;
  begin
do_something
Label1: used inside function
  end;

so, the is the meaning of this error and where is the suitable place to put lables,function to be used inside and outside functions(global variable, labels, function)?.
« Last Edit: April 30, 2015, 02:05:49 pm by hamza »

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: source editor
« Reply #4 on: April 30, 2015, 02:36:27 pm »
Let me clarify a couple of things
1) TForm1 is a custom type. Everything declared inside that type are only accessible from outside a instance of that type (aka form1 variable). To make things easier to understand when we are talking about the type declaration we call it a class and when we are talking for the in memory instance of that class we call it an object.
2) each class needs to be instantiated before it can be used this is achieved by calling its constructor. This constructor is consistently named Create inside the rtl & lcl. Thing of this instantiation as having a pointer you can't use it before you call getmem to assign it a memory address. The same thing for a class you can't use before you call its constructor.
3) All components used in the design of a GUI is based on the same class/object idea and is created automatically for you everytime the tform1.create constructor is called.

Now by moving the label1 declaration outside form1 you created a variable that never got instantiated in the first place and that is where the sigsegv comes from. In order to access those components/controls inside the tform1 you need an instantiated object (form1 variable has a reference to one) and you use a dot "." to access them. eg Form1.Lable1 but I would suiggest to declare your function as part of TForm1 this way you get access to all the local components with out problems and you do not have to care about instantiation etc because the moment that your method is called everything should have been instantiated already. eg.

Code: [Select]
type

  { TForm1 }

  TForm1 = class(TForm)
    Label1: TLabel;

  private
    { private declarations }

  public
    { public declarations }
    function my_function : integer ;
  end;               

var
  Form1: TForm1;
    xxx, : SmallInt  ;/// I understand from your reply this variable will be glopal var(good) <-- true.
implementation

{$R *.lfm}

function TForm1.my_function : integer ;
begin
  do_something;
  Label1: used inside function
end;

Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: source editor
« Reply #5 on: April 30, 2015, 03:32:31 pm »
The notion of type is fundamental to Pascal programming. You cannot declare any variable without at the same time declaring its type. This tells the compiler how much memory needs to be set aside for that variable.
Pascal knows numerous simple types such as smallint which you used in your program. These are declared like this:
Code: [Select]
var
  xxx: smallint;
  aBool: boolean;
The compiler knows how much room these variables occupy in memory, and manages that memory without any further help.

Complex types are generally invented by developers. Often they are named with an initial "T". All GUI programming uses many of these complex types, and each one has to be instantiated before use by calling its constructor. This sets aside the correct amount of memory. TLabel is one such complex type. It is not a type recognised by Object Pascal, not a type built in to the language. So a Pascal compiler does not know about it, unless you give the compiler its declaration (usually via a "uses" clause), and tell the compiler to construct an instance of the variable for you by calling its constructor like this:
Code: [Select]
...
uses StdCtrls, ... ;

var
  aLabel: TLabel;

...
procedure TForm1.SomeProcedure;
begin
  aLabel:=TLabel.Create(Self); // this constructs an instance of TLabel in memory
  ...                    // which is owned by an instance of TForm1 which ensures
                         // its memory is correctly freed at the end of its life
end;

RAD programming saves you having to write this sort of code in full. The mere act of dropping a label from the component palette onto your main form achieves all this automatically. Such code is inserted by the Lazarus IDE into your program files, but much of it is not seen (unless you go looking for it).

hamza

  • Jr. Member
  • **
  • Posts: 52
Re: source editor
« Reply #6 on: May 01, 2015, 06:17:20 pm »
thank you for your help and for the good explanation.

I just have one unit(unit1).
now ,the problem salved for the functions and variables but still have a problem in the labels
i do not know,why  it is not acceptable to use labels inside functions???

when I make run ,the error will be "error identifier not found label" but the label is found , plz see below

 { TForm1 }
    TForm1 = class(TForm)
 Label1: TLabel;
.
.
.


implementation
{$R *.lfm}

function up : integer;
begin 
Label28.Caption := 1;
end;

but when I put the  Label1: TLabel;  below var(global) the error will be""PROJECT RAISED EXCPTION CLASS EXTERNAL SIGSEGV" see below sample code

{ TForm1 }
    TForm1 = class(TForm)

.
.
.
var ////(global)
 Label1: TLabel;

implementation
{$R *.lfm}

function up : integer;
begin 
Label28.Caption := '1';
end;

what is the problem with labels??how we can solve that??

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: source editor
« Reply #7 on: May 01, 2015, 09:40:06 pm »
Two general points:

Snippets of code are generally useless in identifying problems. You need to post the whole unit (or units) so those who try to help can see the full picture.

SIGSEGV errors often mean that a class reference (such as label1) has not been instantiated (if it is global it was initialized to nil by the compiler, and is still pointing to nothing when you attempt to use it later), or that it has not been instantiated correctly.

Perhaps a little working example would help. Begin a new Lazarus project, and drop a TLabel and a TButton on the main form. Set the button's name to BIncrement. Double-click the button to generate an OnClick handler, and double-click somewhere on the empty form to generate an OnCreate handler. Complete the main unit as follows:

Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

        { TForm1 }

  TForm1 = class(TForm)
     BIncrement: TButton;
     Label1: TLabel;
     procedure BIncrementClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    counter: integer;
    procedure UpdateLabel;
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  counter:=0; // not really needed since compiler sets counter to 0 initially
  UpdateLabel;
end;

procedure TForm1.UpdateLabel;
begin
  Inc(counter);
  Label1.Caption:=IntToStr(counter);
end;

procedure TForm1.BIncrementClick(Sender: TObject);
begin
  UpdateLabel;
end;

end.
« Last Edit: May 01, 2015, 09:58:14 pm by howardpc »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: source editor
« Reply #8 on: May 02, 2015, 05:17:16 am »
when I make run ,the error will be "error identifier not found label" but the label is found , plz see below
Learn identifier scoping rule. Label1 is an instance variable of TForm1, while your up is a global function, not TForm1's method. When the function says Label1, whose Label1 does it refer to?
but when I put the  Label1: TLabel;  below var(global) the error will be""PROJECT RAISED EXCPTION CLASS EXTERNAL SIGSEGV" see below sample code
When you do that, Label1 is no longer part of TForm1 and thus, not a subject of auto creation. You have to explicitly create the instance (or object):
Code: [Select]
Label1 := TLabel.Create;BUT, because it's not part of any form, it won't be visible until you assign it to a form by setting its Parent property. I don't think you should go to this level now, though. Better not modify what the designer put, since you may break the lfm <-> source connectivity.

hamza

  • Jr. Member
  • **
  • Posts: 52
Re: source editor
« Reply #9 on: May 02, 2015, 12:21:51 pm »
plz see below(full code)

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }

  public
    { public declarations }

  end;

var
  Form1: TForm1;
  x :integer ;

{$R *.lfm}
implementation

function ss :integer;
begin
  Label1.Caption:=inttostr(x);
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  ss;
  x:= x+1 ;

end;

end.


how we can solve this problem??how to identify the label1???

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: source editor
« Reply #10 on: May 02, 2015, 12:43:31 pm »
Code: [Select]
Form1.Label1.Caption:=inttostr(x);
Or move the function "ss" to private or public section of the form.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: source editor
« Reply #11 on: May 02, 2015, 01:03:07 pm »
plz see below(full code)
Either you didn't read or didn't understand my first answer. Blaazen shows possible solution though it's not the only way.

hamza

  • Jr. Member
  • **
  • Posts: 52
Re: source editor
« Reply #12 on: May 02, 2015, 01:04:30 pm »
Blaazen,thank you for help  :D :D

only using this method is working with my program:
Form1.Label1.Caption:=inttostr(x);

 

TinyPortal © 2005-2018