* * *

Author Topic: I form with some controls and showmessage but close form after message  (Read 974 times)

eldonfsr

  • Full Member
  • ***
  • Posts: 118
Hi i hope you can understand i have a form  some edit control and floatspinedit, but i need to validate the value must be in range great the first floatspin , if not i send showmessage to the user but after i close the message also close the form and i need put a different value.
Code: Pascal  [Select]
  1.  if  FSEMaxStock.Value<= FSEMinStock.Value then begin
  2.       ShowMessage('Maximun Stock must be great than Minimum stock');
  3.       Key:= #27  ;
  4.       FSEMinStock.SetFocus;
  5.  

how i can keep the form still active and type a new value.

thanks...

Handoko

  • Hero Member
  • *****
  • Posts: 2386
  • My goal: build my own game engine using Lazarus
Did you mean you want to do something like this:

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, Forms, Controls, Dialogs, Spin, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     btnSave: TButton;
  16.     btnCancel: TButton;
  17.     fseMin: TFloatSpinEdit;
  18.     fseMax: TFloatSpinEdit;
  19.     Label1: TLabel;
  20.     Label2: TLabel;
  21.     procedure btnCancelClick(Sender: TObject);
  22.     procedure btnSaveClick(Sender: TObject);
  23.   private
  24.     function Validate: Boolean;
  25.   end;
  26.  
  27. var
  28.   Form1: TForm1;
  29.  
  30. implementation
  31.  
  32. {$R *.lfm}
  33.  
  34. { TForm1 }
  35.  
  36. procedure TForm1.btnSaveClick(Sender: TObject);
  37. begin
  38.   if Validate then begin
  39.  
  40.     //
  41.     // do the data saving here
  42.     //
  43.  
  44.     Close;
  45.   end;
  46. end;
  47.  
  48. procedure TForm1.btnCancelClick(Sender: TObject);
  49. begin
  50.   Close;
  51. end;
  52.  
  53. function TForm1.Validate: Boolean;
  54. begin
  55.   Result := True;
  56.   if fseMax.Value >= fseMin.Value then Exit;
  57.   ShowMessage('Maximun Value must be greater or equal to Minimum Value.');
  58.   fseMax.SetFocus;
  59.   Result := False;
  60. end;
  61.  
  62. end.

taazz

  • Hero Member
  • *****
  • Posts: 5150
Hi i hope you can understand i have a form  some edit control and floatspinedit, but i need to validate the value must be in range great the first floatspin , if not i send showmessage to the user but after i close the message also close the form and i need put a different value.
Code: Pascal  [Select]
  1.  if  FSEMaxStock.Value<= FSEMinStock.Value then begin
  2.       ShowMessage('Maximun Stock must be great than Minimum stock');
  3.       Key:= #27  ;
  4.       FSEMinStock.SetFocus;
  5.  

how i can keep the form still active and type a new value.

thanks...
where is this code running from? a button? some otehr control? Does that control have a modalresult property? is it set to mrnone?
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

Handoko

  • Hero Member
  • *****
  • Posts: 2386
  • My goal: build my own game engine using Lazarus
Code: Pascal  [Select]
  1.       Key:= #27  ;
  2.  


I just saw your code set the Esc key. For your information, it is not wise to validate and set focus to that control every time user do a Keypress/KeyDown/KeyUp (or something similar).

It is better to do the validation on EditingDone event. Or even better if the form has a Cancel button.
« Last Edit: June 07, 2018, 05:08:41 am by Handoko »

FTurtle

  • Full Member
  • ***
  • Posts: 229
See attached example project.

Code: Pascal  [Select]
  1. unit Unit2;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ButtonPanel;
  9.  
  10. type
  11.  
  12.   { TForm2 }
  13.  
  14.   TForm2 = class(TForm)
  15.     ButtonPanel1: TButtonPanel;
  16.     Edit1: TEdit;
  17.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  18.   private
  19.  
  20.   public
  21.     IntValue: Integer;
  22.   end;
  23.  
  24. var
  25.   Form2: TForm2;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. { TForm2 }
  32.  
  33. procedure TForm2.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  34. begin
  35.   if ModalResult<>mrOK then
  36.     Exit;
  37.  
  38.   if not TryStrToInt(Edit1.Caption, IntValue) then
  39.   begin
  40.     ShowMessage('It is not Integer.'+LineEnding+'Try again.');
  41.     CloseAction:=caNone;
  42.     ActiveControl:=Edit1;
  43.   end;
  44. end;
  45.  
  46. end.
  47.  

eldonfsr

  • Full Member
  • ***
  • Posts: 118
Thanks fpr your help give me some diferent ideas what did... i dont know if is the right way or not but is working for me.

1 When form is active
Code: Pascal  [Select]
  1. rocedure TFProducInfo.FormActivate(Sender: TObject);
  2. var gpo,SubGpo:string;
  3.     sqlsel:string;
  4.     var CloseAction: TCloseAction ;
  5. begin
  6.      CloseAction:= caNone;
  7.      if SQLQGroup.Active =false then
  8.    begin
  9.        SQLQGroup.Open;
  10.        SQLQGroup.First ;
  11.        cbGroup.Items.Clear;
  12.        while not SQLQGroup.EOF Do
  13.        begin
  14.           cbGroup.Items.Add( SQLQgroup.FieldByName('gpodesc').AsString );
  15.           SQLQGroup.Next;
  16.        end;
  17.    end;
  18.  
  19.    if SQLQSubGpos.Active =false then
  20.    begin
  21.        SQLQSubGpos.Open;
  22.        SQLQSubGpos.First ;
  23.         cbSubGpo.Items.Clear;
  24.        while not SQLQSubGpos.EOF Do
  25.        begin
  26.           cbSubGpo.Items.Add( SQLQSubGpos.FieldByName('subgpodesc').AsString );
  27.           SQLQSubGpos.Next;
  28.        end;
  29.    end;
  30.    if FBrwProdCat.lnew  then begin
  31.       EProd.Text:='';
  32.       EDesc.Text:='';
  33.       cbGroup.ItemIndex:=0;
  34.       cbSubGpo.ItemIndex:=0;
  35.       CBKit.Checked:=false;
  36.       CBService.Checked:=false;
  37.       FSEMinStock.Text:='0';
  38.       FSEMaxStock.Text:='0';
  39.       FSEReorder.Text:='0';
  40.       FSECost.Text:='0';
  41.       FSEPrice.Text:='0';
  42.       EProd.Enabled:=true;
  43.    end
  44.    else
  45.    begin
  46.       EProd.Text:=FBrwProdCat.SQLQProds.FieldByName('product_id').AsString;
  47.       EDesc.Text:=FBrwProdCat.SQLQProds.FieldByName('proddesc').AsString;
  48.       gpo:=FBrwProdCat.SQLQProds.FieldByName('gpo_id').AsString;
  49.       sqlsel:='select * from groups where gpo_id =:gpo';
  50.       SQLQGroup.Close;
  51.       SQLQGroup.SQL.Text:=sqlsel;
  52.       SQLQGroup.ParamByName('gpo').AsString:=gpo;
  53.       SQLQGroup.Open;
  54.       SQLQGroup.First;
  55.       if not SQLQGroup.EOF then begin
  56.          cbgroup.Text:=SQLQGroup.FieldByName('gpodesc').AsString ;
  57.       end
  58.       else
  59.       begin
  60.          cbgroup.Text:='';
  61.       end;
  62.  
  63.       SubGpo:=FBrwProdCat.SQLQProds.FieldByName('subgpo_id').AsString;
  64.       sqlsel:='select * from subgroups where subgpo_id =:SubGpo';
  65.       SQLQSubGpos.Close;
  66.       SQLQSubGpos.SQL.Text:=sqlsel;
  67.       SQLQSubGpos.ParamByName('SubGpo').AsString:=SubGpo;
  68.       SQLQSUbGpos.Open;
  69.       SQLQSubGpos.First;
  70.       if not SQLQSubGpos.EOF then begin
  71.          CBSubGpo.Text:=SQLQSubGpos.FieldByName('subgpodesc').AsString ;
  72.       end
  73.       else
  74.       begin
  75.          cbgroup.Text:='';
  76.       end;
  77.       CBKit.Checked:=FBrwProdCat.SQLQProds.FieldByName('kit').AsBoolean;
  78.       CBService.Checked:=FBrwProdCat.SQLQProds.FieldByName('service').AsBoolean;
  79.       FSEMinStock.Text:=FBrwProdCat.SQLQProds.FieldByName('Min_Stock').AsString;
  80.       FSEMaxStock.Text:=FBrwProdCat.SQLQProds.FieldByName('Max_stock').AsString;
  81.       FSEReorder.Text:=FBrwProdCat.SQLQProds.FieldByName('Reorder').AsString;
  82.       FSECost.Text:=FBrwProdCat.SQLQProds.FieldByName('CostProd').AsString;
  83.       FSEPrice.Text:=FBrwProdCat.SQLQProds.FieldByName('ShellPrice').AsString;
  84.       EProd.Enabled:=false;
  85.    end;
  86. end;          
  87.  
  88.  
create the CloseAction var.


second on Keypress on each SpinEdit  put this code.

Code: Pascal  [Select]
  1. procedure TFProducInfo.FSEMaxStockKeyPress(Sender: TObject; var Key: char);
  2. begin
  3.   if Key = #13  then begin
  4.     if FSEMaxStock.Value<= FSEMinStock.Value then begin
  5.        ShowMessage('Maximun Stock must be great than Minimum stock');
  6.        FSEMaxStock.SetFocus;
  7.     end
  8.     else
  9.     begin
  10.      ActiveControl :=FSEReorder;
  11.       FSEReorder.SetFocus;
  12.     end;
  13.   end;
  14. end;    
  15.  

Handoko

  • Hero Member
  • *****
  • Posts: 2386
  • My goal: build my own game engine using Lazarus
... on Keypress on each SpinEdit  put this code.

Code: Pascal  [Select]
  1. procedure TFProducInfo.FSEMaxStockKeyPress(Sender: TObject; var Key: char);
  2. begin
  3.   if Key = #13  then begin
  4.     if FSEMaxStock.Value<= FSEMinStock.Value then begin
  5.        ShowMessage('Maximun Stock must be great than Minimum stock');
  6.        FSEMaxStock.SetFocus;
  7.     end
  8.     else
  9.     begin
  10.      ActiveControl :=FSEReorder;
  11.       FSEReorder.SetFocus;
  12.     end;
  13.   end;
  14. end;    
  15.  

Not a good solution. I tested it, users can use mouse click or tab key to skip the validation check.

FTurtle

  • Full Member
  • ***
  • Posts: 229
Thanks fpr your help give me some diferent ideas what did... i dont know if is the right way or not but is working for me.

1 When form is active
Code: Pascal  [Select]
  1. ...
  2.  
create the CloseAction var.


second on Keypress on each SpinEdit  put this code.

Code: Pascal  [Select]
  1. ...
  2.  

Few words about your code:

1. Usage of OnActivate event is bad choice for do anything except some seldom cases because possible multiple calling.
   Better places:
  - Constructor
  - OnCreate
  - From outside of form by caller

2.
Quote
    var CloseAction: TCloseAction ;
begin
     CloseAction:= caNone;
CloseAction in FormClose is not a variable but a var-parameter. So, you should not declare it.
"CloseAction:= caNone;" in your code does nothing.
Read documentation:
https://www.freepascal.org/docs-html/ref/refsu65.html#x177-19900014.4.2
http://wiki.freepascal.org/Variable_parameter

3.
Quote
     if SQLQGroup.Active =false then
This is bad style

Code: Pascal  [Select]
  1. var A, B: Boolean;
  2.  
  3. // Bad style
  4. if A=True then
  5.   ...
  6. if B=False then
  7.   ...
  8.  
  9. // Good style
  10. if A then
  11.   ...
  12. if not B then
  13.   ...
  14.  

4.
Quote
     ActiveControl :=FSEReorder;
      FSEReorder.SetFocus;

These two lines do the same.

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus