Recent

Author Topic: Delpi Knowledge learning Lazarus/FPC question...  (Read 1690 times)

1HuntnMan

  • Sr. Member
  • ****
  • Posts: 276
  • From Delphi 7 to Lazarus
    • NewFound Photo Art
Delpi Knowledge learning Lazarus/FPC question...
« on: October 01, 2023, 10:42:48 pm »
I'm transgressing from my knowledge of Delphi 7 to Lazarus.  I wrote 4 systems I used to sell long time ago. I'm now writing a small system for a friend just for the fun of it.  Fairly easy starting out. But from the main form I have a list of speed buttons at the top. Plus you can use the main menu. Then created a form called FrmContacts, Unit Contacts.  Then just to test, I compiled but Lazarus is have an issue with this one procedure that is basically the way I would launch the Contacts form as a result of clicking the Contacts button on the main form.

procedure TPhotoOpsProMainFrm.SpdBtnCntksMgtClick(Sender: TObject);
begin
  Screen.Cursor:= crHourGlass;
  Contacts:= FrmContacts.Create(Self);  <-- Lazarus doesn't like this! Can't compile just because of this!
  FrmContacts.Show;
end;

What's the correct method for launching a form from another form?

Thanks in advance,
1HuntnMan

Paolo

  • Hero Member
  • *****
  • Posts: 538
Re: Delpi Knowledge learning Lazarus/FPC question...
« Reply #1 on: October 01, 2023, 11:16:53 pm »
Maybe
Code: Pascal  [Select][+][-]
  1. ...
  2. FrmContacts:=TFrmContacts.create(self);
  3. ...
  4.  
What is "Contacts" in your code ?
« Last Edit: October 01, 2023, 11:18:48 pm by Paolo »

PierceNg

  • Sr. Member
  • ****
  • Posts: 394
    • SamadhiWeb
Re: Delpi Knowledge learning Lazarus/FPC question...
« Reply #2 on: October 02, 2023, 02:09:52 am »
What's the correct method for launching a form from another form?

Take a look here: https://wiki.freepascal.org/Form_Tutorial#The_Use_of_a_Second_Form

Warfley

  • Hero Member
  • *****
  • Posts: 1748
Re: Delpi Knowledge learning Lazarus/FPC question...
« Reply #3 on: October 02, 2023, 08:58:57 am »
procedure TPhotoOpsProMainFrm.SpdBtnCntksMgtClick(Sender: TObject);
begin
  Screen.Cursor:= crHourGlass;
  Contacts:= FrmContacts.Create(Self);  <-- Lazarus doesn't like this! Can't compile just because of this!
  FrmContacts.Show;
end;

The other posters in this thread probably answered your question already, but I just would like to ask what kind of error is thrown here? Because I suspect it's a TFrmContacts type expected but got TForm.

If that is the case, and Delphi doesn't have the problem, I think this different behavior in fpc vs Delphi may be a bug

rvk

  • Hero Member
  • *****
  • Posts: 6577
Re: Delpi Knowledge learning Lazarus/FPC question...
« Reply #4 on: October 02, 2023, 09:38:43 am »
<-- Lazarus doesn't like this! Can't compile just because of this!
Could you show the EXACT code and EXACT error message.

Because I suspect this code doesn't run in Delphi either.
Look at line 5
Code: Pascal  [Select][+][-]
  1. procedure TPhotoOpsProMainFrm.SpdBtnCntksMgtClick(Sender: TObject);
  2. begin
  3.   Screen.Cursor:= crHourGlass;
  4.   Contacts:= FrmContacts.Create(Self);  <-- Lazarus doesn't like this! Can't compile just because of this!
  5.   FrmContacts.Show;
  6. end;
You assign a Contactform to Contacts (but I suspect FrmContacts probably should be TFrmContacts).
But you also do a .Show for FrmContacts. If FrmContacts is a class, then class.show doesn't work.
For .Show you need to do Instance.Show (so in your case Contacts.Show).

So there is more wrong with this example. Please show exact code that works in Delphi and the error message in Lazarus.

(Also please always use the # button in the editor to mark your code as real code)

BlueIcaro

  • Hero Member
  • *****
  • Posts: 803
    • Blog personal
Re: Delpi Knowledge learning Lazarus/FPC question...
« Reply #5 on: October 02, 2023, 09:40:34 am »
Hello, try this:
Code: [Select]
procedure TPhotoOpsProMainFrm.SpdBtnCntksMgtClick(Sender: TObject);
begin
  Screen.Cursor:= crHourGlass;
  Contacts:= FrmContacts.Create(Self);  <-- Lazarus doesn't like this! Can't compile just because of this!
  Contacts.Show;
end;

/BlueIcaro

1HuntnMan

  • Sr. Member
  • ****
  • Posts: 276
  • From Delphi 7 to Lazarus
    • NewFound Photo Art
Re: Delpi Knowledge learning Lazarus/FPC question...
« Reply #6 on: October 02, 2023, 04:50:41 pm »
Thanks for all the answers... this fixed it:
  procedure TPhotoOpsProMainFrm.SpdBtnCntksMgtClick(Sender: TObject);
  begin
    Screen.Cursor:= crHourGlass;
    FrmContacts.Show;
    //FrmContacts:=TFrmContacts.create(self);
    //Contacts:= FrmContacts.Create(Self);
  end;
But, the HourGlass stays on although the Property Cursor for the FrmContacts is set to default. I'll figure this out, maybe just set it to Default in the code.

Tks, 1HuntnMan

wp

  • Hero Member
  • *****
  • Posts: 12459
Re: Delpi Knowledge learning Lazarus/FPC question...
« Reply #7 on: October 02, 2023, 06:51:40 pm »
The Screen.Cursor overrides the control's Cursor. When you change the Screen.Cursor, you must always do it in pairs: Screen.Cursor := crHourGlass first, your lenghty operation, Screen.Cursor := crDefault. And, since the "lengthy operation" might fail with an exception so that the restoring code will not be executed and the rest of the application's lifetime will stick to the hourglass cursor, you should always wrap the Screen.Cursor changes in a try-finally block:

Code: Pascal  [Select][+][-]
  1. Screen.Cursor := crHourglass;
  2. try
  3.   DoSomeLenghtyOperation;
  4. finally
  5.   Screen.Cursor := crDefault;
  6. end;

Here Screen.Cursor := crDefault will always be executed, even if DoSomeLengthOperation does not complete due to an exception.

Another issue occurs sometimes when above code is called by another method which already had changed the cursor itself. Resetting the cursor to crDefault here thus will remove the cursor of the other operation. Therefore, it is a good idea to store the cursor before changing it to crHourglass and to restore it in "finally", rather than blindly resetting it to crDefault:
Code: Pascal  [Select][+][-]
  1. var
  2.   crs: TCursor;
  3. ....
  4.   crs := Screen.Cursor;
  5.   Screen.Cursor := crHourglass;
  6.   try
  7.     DoSomeLengthyOperation;
  8.   finally
  9.     Screen.Cursor := crs;
  10.   end;

And another complication comes into play if the "lengthy operation" itself is changing the cursor. This means that the cursor should be pushed to and popped from a stack data structure. This stack is handled internally by the Screen.BeginWaitCursor/.EndWaitCursor methods - and this is the method that I would highly recommend:
Code: Pascal  [Select][+][-]
  1. Screen.BeginWaitCursor;
  2. try
  3.   DoSomeLengthOperation;
  4. finally
  5.   Screen.EndWaitCursor;
  6. end;
« Last Edit: October 02, 2023, 06:55:12 pm by wp »

Warfley

  • Hero Member
  • *****
  • Posts: 1748
Re: Delpi Knowledge learning Lazarus/FPC question...
« Reply #8 on: October 02, 2023, 07:25:41 pm »
Could you show the EXACT code and EXACT error message.

Because I suspect this code doesn't run in Delphi either.
Well, it could work, because the constructor, when called on an instance, is just a function that returns self:
Code: Pascal  [Select][+][-]
  1.   TTest = class
  2.     constructor Create;
  3.   end;
  4.  
  5. constructor TTest.Create;
  6. begin
  7.  
  8. end;
  9.  
  10. var
  11.   t1,t2: TTest;
  12. begin
  13.   t1:=TTest.Create;
  14.   t2:=t1.Create;
  15.   WriteLn(t1=t2); // TRUE
  16. end.

One thing with FPC is, that the constructor does not return the type that it is called on, but the type that defines it:
Code: Pascal  [Select][+][-]
  1. type
  2.   TBase=class
  3.     constructor Create;
  4.   end;
  5.  
  6.   TChild=class(TBase);
  7.  
  8. constructor TBase.Create;
  9. begin
  10.  
  11. end;
  12.  
  13. var
  14.   t1,t2: TChild;
  15. begin
  16.   t1:=TChild.Create;
  17.   t2:=t1.Create; // Error TBase expected, TChild got
  18.   WriteLn(t1=t2);
  19. end.
A behavior that I started to suspect to be a bug in FPC some time ago. If Delphi does not have this "bug", but instead t1.Create returns the type of t1 instead of the parent type where Create was defined on, then this example would compile.

In this case basically the following:
Code: Pascal  [Select][+][-]
  1.   Contacts:= FrmContacts.Create(Self);
  2.   FrmContacts.Show;
Would compile just fine, and it would result in the first the constructor code being re-run (which re-initializes the form, probably introducing some memory leaks), and then contacts being assigned to be the same object as FrmContacts. Finally FrmContacts.Show would just show that form.

But I don't have a Delphi version installed to test if Delphi behaves that way (and thereby if the behavior of FPC is indeed a bug)

rvk

  • Hero Member
  • *****
  • Posts: 6577
Re: Delpi Knowledge learning Lazarus/FPC question...
« Reply #9 on: October 02, 2023, 09:02:10 pm »
But I don't have a Delphi version installed to test if Delphi behaves that way (and thereby if the behavior of FPC is indeed a bug)
Yes, it also compiled in Delphi.

But TS mentioned this:
Quote
<-- Lazarus doesn't like this! Can't compile just because of this!
So I expected that there was a problem with compiling of that line.
And a problem with compiling always goes hand in hand with a message.

And such message should be mentioned too. Not just... "it doesn't work" or "it doesn't compile".

B.T.W. Even a TForm.Show (in case FrmContacts really was a class-type) could work if the Show procedure was redefined as a class procedure.
But I wouldn't want to confuse anybody with mentioning that :)

I lately see a lot of topics grow very large because a beginner just didn't mention error-messages.
Everyone is elaborating on possibilities an guessing what could be wrong, while all the time it's just a simple type or lack of explanation by a beginner.


 

TinyPortal © 2005-2018