Recent

Author Topic: Action on button click only works after the second click [SOLVED]  (Read 3683 times)

AlphaInc.

  • Jr. Member
  • **
  • Posts: 93
Hello everybody,

I have written a little tool which acts as a Launcher for a game. The tool itself just executes batch files which do the actual work like change a config of my project.
At every start, the tool checks a config and sets Button.Captions accordingly (it checks an entry in my config and either sets the language to german or english - I've done this with an if-else-condition). This setup works fi$
Code: Pascal  [Select][+][-]
  1. procedure TForm1.confCheck();
  2. var
  3.    MyFile:Text;
  4.    Line1:String;
  5. begin
  6.    AssignFile(MyFile,'../Binaries/conf.ini');
  7.    Reset(MyFile);
  8.    ReadLn(MyFile,Line1);
  9.    CloseFile(MyFile)
  10.  
  11.    if Line2='lang=deu' then
  12.       begin
  13.          Button1.Caption:='German'; //just an example line, I've done this for a lot of Captions
  14.       end
  15.    else
  16.       begin
  17.          Button1.Caption:='English';
  18.       end;
  19.    end;
  20. end;

Now i also want to be able to change the language during runtime. Therefore I have setup a Button, which changes the entry in my conf-file and then calls the procedure I just mentioned to check the conf-file and set the Capti$

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button5Click(Sender: TObject);
  2. begin
  3.    ShellExecute(0,nil,PChar('cmd'),PChar('/c cd  ../Binaries && start changeLang.bat'),nil,1);
  4.    logCheck();
  5. end;

The only problem I run into, is that when I start my tool, I need to click two times on my button for it to act and change the language (But only the first time, afterwards one click is enough to change the language). The scr$

Now my question is, how to I resolve this? Meaning that with the first click, the language will change.

Edit: Through a previous thread I found a workaround where i set a delay of half a second to avoid this but I want to know why this occurs and maybe there is a way to do this without a delay.
« Last Edit: April 03, 2021, 11:16:11 pm by AlphaInc. »

dseligo

  • Hero Member
  • *****
  • Posts: 1671
Re: Action on button click only works after the second click.
« Reply #1 on: April 02, 2021, 11:44:48 pm »
I am not sure what do you mean when you say you have to click two times on a button.
I made a small test project which changes the language as you described and it changes language on first click.

Maybe you have some sort of focus issue.

AlphaInc.

  • Jr. Member
  • **
  • Posts: 93
Re: Action on button click only works after the second click.
« Reply #2 on: April 02, 2021, 11:47:17 pm »
I am not sure what do you mean when you say you have to click two times on a button.
I made a small test project which changes the language as you described and it changes language on first click.

Maybe you have some sort of focus issue.

I will try this tomorrow when I'm back home.
But what I mean is this:

When I click on the button I notice that the batch script starts but the Captions don't change. When I click on that button the second time it changes the Captions. If I click on the Button a third time, it changes the Captions again. The strange thing is, that on first click no change will be executed. I hope this makes it clear what i mean.

Bart

  • Hero Member
  • *****
  • Posts: 5702
    • Bart en Mariska's Webstek
Re: Action on button click only works after the second click.
« Reply #3 on: April 02, 2021, 11:58:00 pm »
You read a variable Line1, but you compare to a variable Line2.

Without some real code, it's hard to tell what you are doing wrong.

Bart

AlphaInc.

  • Jr. Member
  • **
  • Posts: 93
Re: Action on button click only works after the second click.
« Reply #4 on: April 03, 2021, 11:08:54 am »
I am not sure what do you mean when you say you have to click two times on a button.
I made a small test project which changes the language as you described and it changes language on first click.

Maybe you have some sort of focus issue.

I tried your project and that worked fine. Now I've implenetend it into my code but changed it alittle since I don't have croatian langauge in it:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button5Click(Sender: TObject);
  2. var slMyFileStrings:TStringList;
  3. begin
  4.    case sLanguageLine of
  5.     'lang=deu':sLanguageLine:='lang=eng';
  6.     'lang=eng':sLanguageLine:='lang=deu';
  7.    else
  8.     sLanguageLine:='lang=eng';
  9.    end;
  10.  
  11.    slMyFileStrings:=TStringList.Create;
  12.    try
  13.       slMyFileStrings.LoadFromFile(cMyFileName);
  14.       If slMyFileStrings.Count>1 then
  15.       slMyFileStrings[1]:=sLanguageLine;
  16.       slMyFileStrings.SaveToFile(cMyFileName);
  17.    finally
  18.       slMyFileStrings.Free;
  19.    end;
  20.    confCheck();
  21. end;

Now, when the ini-Line is set to lang=deu it changes the langauge perfectly (on first click) but when it's set to lang=eng it totally ignores the first click (no langauge change and also no change in the ini file) I assume I have made a mistake by implementing your code so it would be nice if you could help me one more time   :)

dseligo

  • Hero Member
  • *****
  • Posts: 1671
Re: Action on button click only works after the second click.
« Reply #5 on: April 03, 2021, 12:30:39 pm »
Insert ShowMessage in the beginning of click method.
What does it say when ini is set to 'lang=eng' and you click a button?

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button5Click(Sender: TObject);
  2. var slMyFileStrings:TStringList;
  3. begin
  4.   ShowMessage(sLanguageLine); // insert this line
  5.    case sLanguageLine of

AlphaInc.

  • Jr. Member
  • **
  • Posts: 93
Re: Action on button click only works after the second click.
« Reply #6 on: April 03, 2021, 12:36:14 pm »
Insert ShowMessage in the beginning of click method.
What does it say when ini is set to 'lang=eng' and you click a button?

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button5Click(Sender: TObject);
  2. var slMyFileStrings:TStringList;
  3. begin
  4.   ShowMessage(sLanguageLine); // insert this line
  5.    case sLanguageLine of

It gives me an empy message-box. After I click another time it says lang=eng.

Bart

  • Hero Member
  • *****
  • Posts: 5702
    • Bart en Mariska's Webstek
Re: Action on button click only works after the second click.
« Reply #7 on: April 03, 2021, 12:38:44 pm »
B.t.w: why don't you use TIniFile to handle Ini-files?
For starters it does not care on which (hardcoded) line the information you need is.

And again, don't show only code snippets. Without contect it's almost impossible to say what you did wrong.

Bart

AlphaInc.

  • Jr. Member
  • **
  • Posts: 93
Re: Action on button click only works after the second click.
« Reply #8 on: April 03, 2021, 12:50:18 pm »
B.t.w: why don't you use TIniFile to handle Ini-files?
For starters it does not care on which (hardcoded) line the information you need is.

And again, don't show only code snippets. Without contect it's almost impossible to say what you did wrong.

Bart

To be honest, AssignMyFile was fromt the time when i thought I watend to use text-file, I only switched to .ini since someone told me to.

This is my whole code:

Code: Pascal  [Select][+][-]
  1. {
  2. unit Unit1;
  3.  
  4. {$mode objfpc}{$H+}
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls,
  10.   ShellAPI, Buttons, ExtCtrls, StdCtrls, MMSystem;
  11.  
  12. type
  13.  
  14.   { TForm1 }
  15.  
  16.   TForm1 = class(TForm)
  17.     Button1: TButton;
  18.     Button2: TButton;
  19.     Button3: TButton;
  20.     Button4: TButton;
  21.     Button5: TButton;
  22.     Button6: TButton;
  23.     Button7: TButton;
  24.     Button8: TButton;
  25.     Button9: TButton;
  26.     Image1: TImage;
  27.     Image2: TImage;
  28.     Image3: TImage;
  29.     PageControl1: TPageControl;
  30.     TabSheet1: TTabSheet;
  31.     TabSheet2: TTabSheet;
  32.     procedure Button1Click(Sender: TObject);
  33.     procedure Button2Click(Sender: TObject);
  34.     procedure Button3Click(Sender: TObject);
  35.     procedure Button4Click(Sender: TObject);
  36.     procedure Button5Click(Sender: TObject);
  37.     procedure Button6Click(Sender: TObject);
  38.     procedure Button7Click(Sender: TObject);
  39.     procedure Button8Click(Sender: TObject);
  40.     procedure Button9Click(Sender: TObject);
  41.     procedure music();
  42.     procedure confCheck();
  43.   private
  44.     sLanguageLine:String;
  45.   public
  46.  
  47.   end;
  48.  
  49. var
  50.   Form1: TForm1;
  51.  
  52. implementation
  53.  
  54. {$R *.lfm}
  55.  
  56. { TForm1 }
  57.  
  58. const cMyFileName='conf.ini';
  59.  
  60. procedure TForm1.Button1Click(Sender: TObject);
  61. begin
  62.    ShellExecute(0,nil,PChar('cmd'),PChar('/c cd ../Binaries && start.bat'),nil,1);
  63.    Close;
  64. end;
  65.  
  66. procedure TForm1.Button2Click(Sender: TObject);
  67. begin
  68.    PageControl1.ActivePageIndex:=1;
  69. end;
  70.  
  71. procedure TForm1.Button3Click(Sender: TObject);
  72. begin
  73.    ShellExecute(0,nil,PChar('cmd'),PChar('/c cd ../Binaries && start init.bat'),nil,1);
  74.    Button3.Enabled:=false
  75. end;
  76.  
  77. procedure TForm1.Button4Click(Sender: TObject);
  78. begin
  79.    Close;
  80. end;
  81.  
  82. procedure TForm1.Button5Click(Sender: TObject);
  83. var slMyFileStrings:TStringList;
  84. begin
  85.    ShowMessage(sLanguageLine);
  86.    case sLanguageLine of
  87.     'lang=deu':sLanguageLine:='lang=eng';
  88.     'lang=eng':sLanguageLine:='lang=deu';
  89.    else
  90.     sLanguageLine:='lang=eng';
  91.    end;
  92.  
  93.    slMyFileStrings:=TStringList.Create;
  94.    try
  95.       slMyFileStrings.LoadFromFile(cMyFileName);
  96.       If slMyFileStrings.Count>1 then
  97.       slMyFileStrings[1]:=sLanguageLine;
  98.       slMyFileStrings.SaveToFile(cMyFileName);
  99.    finally
  100.       slMyFileStrings.Free;
  101.    end;
  102.    confCheck();
  103. end;
  104.  
  105. procedure TForm1.Button6Click(Sender: TObject);
  106. begin
  107.    ShellExecute(0,nil,PChar('cmd'),PChar('/c cd ../Binaries && start changeVers.bat'),nil,1);
  108. end;
  109.  
  110. procedure TForm1.Button7Click(Sender: TObject);
  111. begin
  112.    ShellExecute(0,nil,PChar('cmd'),PChar('/c cd ../Binaries && start changeEnhancements.bat'),nil,1);
  113. end;
  114.  
  115. procedure TForm1.Button8Click(Sender: TObject);
  116. begin
  117.    ShellExecute(0,nil,PChar('cmd'),PChar('/c cd ../Binaries && start changeMods.bat'),nil,1);
  118. end;
  119.  
  120. procedure TForm1.Button9Click(Sender: TObject);
  121. begin
  122.    PageControl1.ActivePageIndex:=0;
  123. end;
  124.  
  125. //Systemjunk
  126.  
  127. procedure TForm1.music();
  128. begin
  129.   PlaySound('../Binaries/theme.wav',0,SND_ASYNC or SND_LOOP);
  130. end;
  131.  
  132. procedure TForm1.confCheck();
  133. var
  134.    MyFile:Text;
  135.    Line1,Line2,Line3,Line4,Line5:String;
  136. begin
  137.    AssignFile(MyFile,cMyFileName);
  138.    Reset(MyFile);
  139.    ReadLn(MyFile,Line1);
  140.    ReadLn(MyFile,Line2);
  141.    ReadLn(MyFile,Line3);
  142.    ReadLn(MyFile,Line4);
  143.    ReadLn(MyFile,Line5);
  144.    CloseFile(MyFile);
  145.  
  146.    if Line1='init=1' then
  147.       Button3.Enabled:=false
  148.    else
  149.       Button3.Enabled:=true;
  150.  
  151.    if Line2='lang=deu' then
  152.       begin
  153.          Button1.Caption:='Starten';
  154.          Button2.Caption:='Eintellungen';
  155.          Button3.Caption:='Initialisieren';
  156.          Button4.Caption:='Beenden';
  157.          Button5.Caption:='Sprache ändern';
  158.          Button9.Caption:='Zurück';
  159.             if Line3='vers=rem' then
  160.                if Line4='enhancements=0' then
  161.                   if Line5='mods=0' then
  162.                      begin
  163.                         Button6.Caption:='Original laden';
  164.                         Button7.Caption:='Enhancements aktivieren';
  165.                         Button8.Caption:='Mods aktivieren';
  166.                      end
  167.                   else
  168.                      begin
  169.                         Button6.Caption:='Original laden';
  170.                         Button7.Caption:='Enhancements aktivieren';
  171.                         Button8.Caption:='Mods deaktivieren';
  172.                      end
  173.                else
  174.                   if Line5='mods=0' then
  175.                      begin
  176.                         Button6.Caption:='Original laden';
  177.                         Button7.Caption:='Enhancements deaktivieren';
  178.                         Button8.Caption:='Mods aktivieren';
  179.                      end
  180.                   else
  181.                      begin
  182.                         Button6.Caption:='Original laden';
  183.                         Button7.Caption:='Enhancements deaktivieren';
  184.                         Button8.Caption:='Mods deaktivieren';
  185.                      end
  186.  
  187.             else
  188.                if Line4='enhancements=0' then
  189.                   if Line5='mods=0' then
  190.                      begin
  191.                         Button6.Caption:='Remastered laden';
  192.                         Button7.Caption:='Enhancements aktivieren';
  193.                         Button8.Caption:='Mods aktivieren';
  194.                      end
  195.                   else
  196.                      begin
  197.                         Button6.Caption:='Remastered laden';
  198.                         Button7.Caption:='Enhancements aktivieren';
  199.                         Button8.Caption:='Mods deaktivieren';
  200.                      end
  201.                else
  202.                   if Line5='mods=0' then
  203.                      begin
  204.                         Button6.Caption:='Remastered laden';
  205.                         Button7.Caption:='Enhancements dekativieren';
  206.                         Button8.Caption:='Mods aktiveren';
  207.                      end
  208.                   else
  209.                      begin
  210.                         Button6.Caption:='Remastered laden';
  211.                         Button7.Caption:='Enhancements deaktivieren';
  212.                         Button8.Caption:='Mods deaktivieren';
  213.                      end
  214.       end
  215.    else if Line2='lang=eng' then
  216.       begin
  217.          Button1.Caption:='Start';
  218.          Button2.Caption:='Settings';
  219.          Button3.Caption:='Initialize';
  220.          Button4.Caption:='Close';
  221.          BUtton5.Caption:='Change Langauge';
  222.          Button9.Caption:='Back';
  223.             if Line3='vers=rem' then
  224.                if Line4='enhancements=0' then
  225.                   if Line5='mods=0' then
  226.                      begin
  227.                         Button6.Caption:='Load Original';
  228.                         Button7.Caption:='Activate Enhancements';
  229.                         Button8.Caption:='Activate Mods';
  230.                      end
  231.                   else
  232.                      begin
  233.                         Button6.Caption:='Load Original';
  234.                         Button7.Caption:='Activate Enhancements';
  235.                         Button8.Caption:='Deactivate Mods';
  236.                      end
  237.                else
  238.                   if Line5='mods=0' then
  239.                      begin
  240.                         Button6.Caption:='Load Original';
  241.                         Button7.Caption:='Deactivate Enhancements';
  242.                         Button8.Caption:='Activate Mods';
  243.                      end
  244.                   else
  245.                      begin
  246.                         Button6.Caption:='Load Original';
  247.                         Button7.Caption:='Deactivate Enhancements';
  248.                         Button8.Caption:='Deactivate Mods';
  249.                      end
  250.             else
  251.                if Line4='enhancements=0' then
  252.                   if Line5='mods=0' then
  253.                      begin
  254.                         Button6.Caption:='Load Remastered';
  255.                         Button7.Caption:='Activate Enhancements';
  256.                         Button8.Caption:='Activate Mods';
  257.                      end
  258.                   else
  259.                      begin
  260.                         Button6.Caption:='Load Remastered';
  261.                         Button7.Caption:='Activate Enhancements';
  262.                         Button8.Caption:='Deactivate Mods';
  263.                      end
  264.                else
  265.                   if Line5='mods=0' then
  266.                      begin
  267.                         Button6.Caption:='Load Remastered';
  268.                         Button7.Caption:='Deactivate Enhancements';
  269.                         Button8.Caption:='Activate Mods';
  270.                      end
  271.                   else
  272.                      begin
  273.                         Button6.Caption:='Load Remastered';
  274.                         Button7.Caption:='Deactivate Enhancements';
  275.                         Button8.Caption:='Deactivate Mods';
  276.                      end;
  277.    end;
  278. end;
  279.  
  280.  
  281. end.
  282.  

dseligo

  • Hero Member
  • *****
  • Posts: 1671
Re: Action on button click only works after the second click.
« Reply #9 on: April 03, 2021, 01:01:06 pm »
You are missing OnCreate event:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.    MyFile:Text;
  4. begin
  5.   If not FileExists(cMyFileName) then
  6.   begin
  7.     AssignFile(MyFile,cMyFileName);
  8.     Rewrite(MyFile);
  9.     WriteLn(MyFile,'Line1');
  10.     WriteLn(MyFile,'lang=eng');
  11.     CloseFile(MyFile);
  12.   end;
  13.   confCheck;
  14. end;

This is meant to read ini file in the beginning of your program.

Omit 'if' block if you are sure that you always have ini file. In this 'if' block you can write default values in ini file if someone accidently deletes it or when the app is first started.

Simpler version:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   confCheck;
  4. end;
« Last Edit: April 03, 2021, 01:06:27 pm by dseligo »

AlphaInc.

  • Jr. Member
  • **
  • Posts: 93
Re: Action on button click only works after the second click.
« Reply #10 on: April 03, 2021, 01:07:58 pm »
You are missing OnCreate event:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.    MyFile:Text;
  4. begin
  5.   If not FileExists(cMyFileName) then
  6.   begin
  7.     AssignFile(MyFile,cMyFileName);
  8.     Rewrite(MyFile);
  9.     WriteLn(MyFile,'Line1');
  10.     WriteLn(MyFile,'lang=eng');
  11.     CloseFile(MyFile);
  12.   end;
  13.   confCheck;
  14. end;

This is meant to read ini file in the beginning of your program.

Omit 'if' block if you are sure that you always have ini file. In this 'if' block you can write default values in ini file if someone accidently deletes it or when the app is first started.

Simpler version:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   confCheck;
  4. end;

That didn't fix the problem. Still get an empty message-box when language is set to english in the ini at starup.

dseligo

  • Hero Member
  • *****
  • Posts: 1671
Re: Action on button click only works after the second click.
« Reply #11 on: April 03, 2021, 01:31:25 pm »
That didn't fix the problem. Still get an empty message-box when language is set to english in the ini at starup.
Did you double click on empty space of your form to create OnClick event (or assigned it manually in Object inspector)?

Oh, and change the start of confCheck(), I just see you still read it in Line2 instead of sLanguageLine:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.confCheck();
  2. var
  3.    MyFile:Text;
  4.    Line1,Line2,Line3,Line4,Line5:String;
  5. begin
  6.    AssignFile(MyFile,cMyFileName);
  7.    Reset(MyFile);
  8.    ReadLn(MyFile,Line1);
  9.    ReadLn(MyFile,Line2);
  10.   If (Line2<>'lang=deu') and (Line2<>'lang=eng') then Line2:='lang=eng'; // new line
  11.   sLanguageLine:=Line2; // new line
  12.    ReadLn(MyFile,Line3);
  13.    ReadLn(MyFile,Line4);
  14.    ReadLn(MyFile,Line5);
  15.    CloseFile(MyFile);

dseligo

  • Hero Member
  • *****
  • Posts: 1671
Re: Action on button click only works after the second click.
« Reply #12 on: April 03, 2021, 01:41:51 pm »
One more thing: Lazarus has support for internationalization.
For couple of captions you could do it manually, but as you continue to develop your application you may find it easier to use Lazarus' built-in internationalization support.

If you are interested in this, here are a couple of links to get you started:
https://wiki.freepascal.org/Translations_/_i18n_/_localizations_for_programs
https://wiki.freepascal.org/Step-by-step_instructions_for_creating_multi-language_applications
https://wiki.freepascal.org/Lazarus_Documentation#Translating.2FInternationalization.2FLocalization
https://wiki.freepascal.org/Everything_else_about_translations

When you use this localization support, it's also very easy to add another language.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8545
Re: Action on button click only works after the second click.
« Reply #13 on: April 03, 2021, 03:42:40 pm »
I'd normally suspect a dangling else as the cause of this, but #8 (the only place the entire code has been posted) doesn't show anything obvious.

I would, however, as a preventative measure replace some more of those if...then...else statements with case statements, and would make sure that each case has an otherwise clause even if this only contained an error message: case...otherwise is identical in effect to case...else but avoids confusion.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

dseligo

  • Hero Member
  • *****
  • Posts: 1671
Re: Action on button click only works after the second click.
« Reply #14 on: April 03, 2021, 03:52:09 pm »
I'd normally suspect a dangling else as the cause of this, but #8 (the only place the entire code has been posted) doesn't show anything obvious.
The reason is that variable sLanguageLine isn't initialized at the beginning.

 

TinyPortal © 2005-2018