Recent

Author Topic: Best way to exchange data between a form and a unit  (Read 47214 times)

Hansvb

  • Hero Member
  • *****
  • Posts: 685
Re: Best way to exchange data between a form and a unit
« Reply #225 on: August 25, 2024, 10:06:17 am »
Hi,

This is something I don't understand. It works, but I would actually think that this shouldn't work.

In the language file I created a new section and I also added this section to the Sects array.

When I enter the writeToLog function (see attachment) , lDummy is 0. That's good because I'm coming from view.main and that is section 0 in the language file and index 0 in the Sects array. When I view LogString it has the correct contents. Why is this found even though it is in section 3?

Is the section only important for:
Code: Pascal  [Select][+][-]
  1. procedure TPresenterMain.GetStaticTexts(const aSection: string); //=^
  2. var
  3.   lsl: IStringList;
  4.   lt: integer;
  5.   lreason: TProviderReason;
  6. begin { due to usage of 'out'-param, 'lt' can't be anything else than integer }
  7.   lsl:= fModel.GetStaticTexts(aSection,lt);
  8.   case lt of
  9.     0: lreason:= prMainStaticTexts; // remember to correlate with model.sects
  10.     1: lreason:= prConfigStaticTexts; // i.e.: the more units = more selectors
  11.     //2: next view
  12.   end;
  13.   ...
  14. end;


and for the rest, always looks at the entire language file? Then it should never contain a double name.

cdbc

  • Hero Member
  • *****
  • Posts: 1496
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #226 on: August 25, 2024, 11:49:43 am »
Hi Hans
Mmmm... In such a seemingly simple mechanism, there lurks a couple of "Gotcha"s, here and there.
Did you by any chance, forget what you should remember?!? Look for remember below:
Code: Pascal  [Select][+][-]
  1. procedure TfeaModelMain.DoEach(const aValue: string; const anIdx: ptrint;
  2.                                anObj: TObject; aData: pointer);  
  3. var ls: string; lid: integer;
  4. begin
  5.   if fSecId = -1 then exit;
  6.   ls:= LeftWord(aValue);
  7.   lid:= IndexText(ls,Sects);
  8.   if lid = fSecId then begin
  9.     IStringList(aData).Append(aValue); //<- new feature <aData> typecast :o)
  10.     fInSection:= true;
  11.   end else begin
  12.     if fInSection then begin
  13.       case lid of
  14.         0..2: fInSection:= false; /// remember to adjust selector-values according to 'Sects'
  15.       end;
  16.       if fInSection then IStringList(aData).Append(aValue); //<- new feature <aData>
  17.     end;
  18.   end;
  19. end;
those 'selectors' decide, when the 'Section' stops loading, so that you only get 1 section! Otherwise, it stops at list-end.
These 'case-selectors' need to correlate with the 'Sects' array, because 'lid' & 'fSecId' constantly monitors what comes through this little search engine...
Just off the bat, that might be your problem...
Regards Benny
« Last Edit: August 25, 2024, 11:53:36 am by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

cdbc

  • Hero Member
  • *****
  • Posts: 1496
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #227 on: August 25, 2024, 12:20:19 pm »
Hi
Right, so I tried to "Pull wool over the compiler's eyes" and use a 'writable const' as the /upper/ selector in the 'DoEach' case statement  :-X ...The compiler would have NONE of that!  >:D
My plan was to set that in the constructor to high(Sects)... no more remembering, that idea <crashed and burned>
So here is a workaround, that makes it easier to remember.
in 'model.main':
Code: Pascal  [Select][+][-]
  1.   { TfeaModelMain }
  2.   TfeaModelMain = class(TObject,IfeaModelMain)
  3.   private { remember to add your views to this array, maybe add a 'RegisterSection' method?!? }
  4.   const Sects: TStringArray = ('[view.main]','[TfeaModelMain]','[TfeaPresenterMain]');
  5.   const SectMaxIdx = 2; { used as selector in 'DoEach', indicates highest idx of 'Sects' }
  6.   var                                              
  7.     fInSection: boolean; // used while searching static text sections
  8.     fSecId: integer; // tmp id while searching
  9.     function Obj: TObject;
  10.   protected
and in 'DoEach':
Code: Pascal  [Select][+][-]
  1.     if fInSection then begin
  2.       case lid of
  3.         0..SectMaxIdx: fInSection:= false; /// remember to adjust selector-values according to 'Sects'
  4.       end;
  5.       if fInSection then IStringList(aData).Append(aValue); //<- new feature <aData>
  6.     end;
Just a tip...  :D
Regards Benny
« Last Edit: August 25, 2024, 12:24:45 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

cdbc

  • Hero Member
  • *****
  • Posts: 1496
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #228 on: August 25, 2024, 12:45:16 pm »
Hi again
I prefer 'case .. of' over 'if .. then .. else ..', so that's why I didn't think of this before, can you please test this:
Code: Pascal  [Select][+][-]
  1. procedure TfeaModelMain.DoEach(const aValue: string; const anIdx: ptrint;
  2.                                anObj: TObject; aData: pointer);  
  3. var ls: string; lid: integer;
  4. begin
  5.   if fSecId = -1 then exit;
  6.   ls:= LeftWord(aValue);
  7.   lid:= IndexText(ls,Sects);
  8.   if lid = fSecId then begin
  9.     IStringList(aData).Append(aValue); //<- new feature <aData> typecast :o)
  10.     fInSection:= true;
  11.   end else begin
  12.     if fInSection then begin
  13.       /// area 51 ///
  14.       if ((lid >= 0) and (lid <= high(Sects))) then fInSection:= false;
  15.       /// area 51 ///
  16. (*
  17.       case lid of
  18.         0..SectMaxIdx: fInSection:= false; /// remember to adjust selector-values according to 'Sects'
  19.       end;
  20. *)
  21.       if fInSection then IStringList(aData).Append(aValue); //<- new feature <aData>
  22.     end;
  23.   end;
  24. end;
Regards Benny
« Last Edit: August 25, 2024, 01:07:43 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Hansvb

  • Hero Member
  • *****
  • Posts: 685
Re: Best way to exchange data between a form and a unit
« Reply #229 on: August 25, 2024, 04:55:49 pm »
I see you have been busy while I have been fishing. I have made your adjustments and everything works fine now.

I had made 2 mistakes.
The first was indeed:
Quote
Did you by any chance, forget what you should remember?!? Look for remember below:
  :-[ I had not changed DoEach.

The second was that I had copied the 2 language files to the program directory and then modified them there. And  did not remove  the 2 file from the common directory. So  i did not notice that i was looking in the wrong directory.
This was still wrong :
Code: Pascal  [Select][+][-]
  1. mvpTexts = '%scommon'+PathDelim+'mvptexts.ini'; // <-- remember to change to your choice  
  Changed to:
Code: Pascal  [Select][+][-]
  1. mvpTexts = '%s'+'mvptexts.%s'; // <-- remember to change to your choice
I know, i must read better, you already anticipated it in the comment.  O:-)

Now I can read a newly  added section.

 

TinyPortal © 2005-2018