I have two TEdit boxes that I am using to specify file paths, one is for UNC paths, the other is for a local path. However, I would like it so if the user can only enter text in one box. If they enter text in one box, it should clear the other one. How should I go about doing this? Also, not sure if I should use an OnEnter, OnChange, or some other method.
You can do it pretty simply. Create one OnChange handler, and assign it to both TEdits using the Object Inspector's Events tab. Then you can use something like the following:
procedure TForm1.EditChanged(Sender: TObject); //Sender is the edit being changed
begin
if Sender = UNCEdit then // If it's is the UNCEdit being changed
begin
LocalPathEdit.OnChange := nil; // Prevent recursive calling!
LocalPathEdit.Text := ''; // Clear the text
LocalPathEdit.OnChange := EditChanged; // Restore the event handler
end;
else
begin
UNCEdit.OnChange := nil;
UNCEdit.Text := '';
UNCEdit.OnChange := EditChanged;
end;
end;
This can be streamlined slightly, but it's not quite as readable to others. It can also be protected with a try..finally, although for simply clearing an edit's text content it's not really needed.
procedure TForm1.EditChanged(Sender: TObject);
var
TmpEdit: TEdit;
begin
if Sender = UNCEdit then
TmpEdit := LocalPathEdit
else
TmpEdit := UNCEdit;
TmpEdit.OnChange := nil;
try
TmpEdit.Text := '';
finally
TmpEdit.OnChange := EditChanged;
end;
end;
If you want to keep the two edit boxes, this is how I would do it.
procedure TForm1.Edit1Exit(Sender: TObject);
begin
if (Edit1.text <> '') then
Edit2.text:= '';
end;
procedure TForm1.Edit2Exit(Sender: TObject);
begin
if (Edit2.text <> '') then
Edit1.text:= '';
end;
You want the value check so that you don't accidentally wipe the value when your users tab through the fields.
You could hook both edit boxes to the following KeyPress event
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
If Sender = Edit1 then
Edit2.clear
else
if Sender = Edit2 then
Edit1.clear;
end;
Related
I am currently doing a school project, I am making a Credit Card machine. I need the 'Enter Button' to
run different code when it is clicked. The first click must get the card number from an edit ps... (I clear the edit once the card number has been retrieved), and the second click must get the pin from the same edit.
How would I do this?
procedure TfrmMainMenu.btbtnEnterClick(Sender: TObject);
var
sCvv,sPin:string;
begin
iCount2:=0;
sCardNumber:=lbledtCardInfo.Text;
if (Length(sCardNumber)<>16) AND (iCount2=0) then
begin
ShowMessage('Card number has to 16 digits,please try again!!');
end
else
begin
Inc(iCount2);
lbledtCardInfo.clear;
lbledtCardInfo.EditLabel.Caption:='Enter Pin' ;
btbtnEnter.Enabled:=false;
end; //if
if iCount2=2 then
begin
btbtnEnter.Enabled:=true;
sPin:=lbledtCardInfo.Text;
ShowMessage(sPin);//returns a blank
end;
You could try to do everything in a single event handler. There are several different ways to handle that. However, a different solution would be to use separate event handlers for each task, and then each task can assign a new handler for the next click to perform, eg:
procedure TfrmMainMenu.FormCreate(Sender: TObject);
begin
// you can set this at design-time if desired...
btbtnEnter.OnClick := GetCCNumber;
end;
procedure TfrmMainMenu.GetCCNumber(Sender: TObject);
begin
sCardNumber := lbledtCardInfo.Text;
if Length(sCardNumber) <> 16 then
begin
ShowMessage('Card number has to 16 digits,please try again!!');
Exit;
end;
lbledtCardInfo.Clear;
lbledtCardInfo.EditLabel.Caption := 'Enter Pin' ;
btbtnEnter.OnClick := GetCCPin;
end;
procedure TfrmMainMenu.GetCCPin(Sender: TObject);
var
sPin: string;
begin
sPin := lbledtCardInfo.Text;
if Length(sPin) <> 4 then
begin
ShowMessage('Card Pin has to 4 digits,please try again!!');
Exit;
end;
ShowMessage(sPin);
...
lbledtCardInfo.Clear;
lbledtCardInfo.EditLabel.Caption := 'Enter Number' ;
btbtnEnter.OnClick := GetCCNumber;
end;
A variation of this would be to create multiple buttons that overlap each other in the UI, and then you can toggle their Visible property back and forth as needed, eg:
procedure TfrmMainMenu.FormCreate(Sender: TObject);
begin
// you can set this at design-time if desired...
btbtnCCPinEnter.Visible := False;
btbtnCCNumEnter.Visible := True;
end;
procedure TfrmMainMenu.btbtnCCNumEnterClick(Sender: TObject);
begin
sCardNumber := lbledtCardInfo.Text;
if Length(sCardNumber) <> 16 then
begin
ShowMessage('Card number has to 16 digits,please try again!!');
Exit;
end;
lbledtCardInfo.Clear;
lbledtCardInfo.EditLabel.Caption := 'Enter Pin' ;
btbtnCCNumEnter.Visible := False;
btbtnCCPinEnter.Visible := True;
end;
procedure TfrmMainMenu.btbtnCCPinEnterClick(Sender: TObject);
var
sPin: string;
begin
sPin := lbledtCardInfo.Text;
if Length(sPin) <> 4 then
begin
ShowMessage('Card Pin has to 4 digits,please try again!!');
Exit;
end;
ShowMessage(sPin);
...
lbledtCardInfo.Clear;
lbledtCardInfo.EditLabel.Caption := 'Enter Number' ;
btbtnCCPinEnter.Visible := False;
btbtnCCNumEnter.Visible := True;
end;
Notice that you test iCount2 = 0 immediately after setting iCount2 := 0. Thus, that test will always be True. Furthermore, the later test iCount2 = 2 will always be False because the value starts at 0 and you only have one Inc in between.
Instead try the following.
Add two string fields FCardNumber and FPin to your form class:
private
FCardNumber: string;
FPin: string;
Also create an enumerated type TEntryStage = (esCardNumber, esPin) and add a field of this type. This will make your code look like this:
private
type
TEntryStage = (esCardNumber, esPin);
var
FCardNumber: string;
FPin: string;
FEntryStage: TEntryStage;
In Delphi, class fields (class member variables) are always initialized, so FEntryStage will be esCardNumber (=TEntryStage(0)) when the form is newly created.
Add a TLabeledEdit (I see you use those) and a TButton; name them eInput and btnNext, respectively. Let the labeled edit's caption be Card number: and the caption of the button be Next.
Now add the following OnClick handler to the button:
procedure TForm1.btnNextClick(Sender: TObject);
begin
case FEntryStage of
esCardNumber:
begin
// Save card number
FCardNumber := eInput.Text;
// Prepare for the next stage
eInput.Clear;
eInput.EditLabel.Caption := 'Pin:';
FEntryStage := esPin;
end;
esPin:
begin
// Save pin
FPin := eInput.Text;
// Just do something with the data
ShowMessageFmt('Card number: %s'#13#10'Pin: %s', [FCardNumber, FPin]);
end;
end;
end;
You might notice that you cannot trigger the Next button using Enter, which is very annoying. To fix this, do
procedure TForm1.eInputEnter(Sender: TObject);
begin
btnNext.Default := True;
end;
procedure TForm1.eInputExit(Sender: TObject);
begin
btnNext.Default := False;
end;
Much better!
I have to open many forms in an application and I'm using a TtoolButton and TActionlist as a menu bar. I coded a procedure to create/show each form. I'm having difficult to trigger Form OnActivate event inside this procedure.
Each form is opened inside a Tpanel which is located in the main form FormHome.
I appreciatte your help !
See my code in Delphi 10.2
procedure TFormHome.PR_OpenForm(Pform : TFormClass);
var
vform : TForm;
begin
vform := Pform.Create(Application);
vform.Parent := PanelCorpo;
vform.Align := alclient;
vform.BorderIcons := [biSystemMenu];
vform.BorderStyle := bsNone;
vform.Show;
vform.SetFocus;
vform.OnActivate(??); // That is the issue, how to call this event ?
end;
Thanks in advance !
**Adding complimentary information to explain why I need one single method to create/open my forms **
This is the code I use to open each particular forms. I have one method to each form with exactly the same code. The only difference is the Form instance itself :
procedure TFormHome.OpenDiretorioExecute(Sender: TObject);
begin
if Not Assigned(FormDiretorio) then
begin
FormDiretorio := TFormDiretorio.Create(Self);
FormDiretorio.Parent := PanelCorpo;
FormDiretorio.Align := alclient;
FormDiretorio.BorderIcons := [biSystemMenu];
FormDiretorio.BorderStyle := bsNone;
FormDiretorio.Show;
FormDiretorio.SetFocus;
FormDiretorio.OnActivate(Sender); // In this way , OnActivate works fine
end;
end;
What I need/want :
I need only one method to open all forms. This TFormHome.PR_OpenForm(Pform : TFormClass) coded above is almost there, except by the OnActivate method that is not working !
Could you help me to fix that ?
Thanks!
Sample Code - Project with Old code and new code
===> Main Form "FormHome"
... // This is the main Form FormHOme which calls FormA, FormB and FormC
// There is a TToolbar with 3 Toolbutton that uses a TActionlist
// FormA and FormB are called by the old style method Action1Execute
// and Action2Execute
// FormC is called by the new method PR_CreateOpenForm , which
// presents the error
var
FormHome: TFormHome;
implementation
uses
UnitFormA,
unitFormB,
UnitFormC;
{$R *.dfm}
procedure TFormHome.Action1Execute(Sender: TObject);
// Action1 : OnExecute event, called from ToolButton1
begin
if Not Assigned(FormA) then
begin
FormA := TFormA.Create(Self);
end;
FormA.Parent := Panelhome;
FormA.Align := alclient;
FormA.BorderIcons := [biSystemMenu];
FormA.BorderStyle := bsNone;
FormA.Show;
FormA.SetFocus;
FormA.OnActivate(Sender); // There is a code in OnActivate event in FormA
end;
procedure TFormHome.Action2Execute(Sender: TObject);
// Action2 : OnExecute event , called from ToolButton2
begin
if Not Assigned(FormB) then
begin
FormB := TFormB.Create(Self);
end;
FormB.Parent := Panelhome;
FormB.Align := alclient;
FormB.BorderIcons := [biSystemMenu];
FormB.BorderStyle := bsNone;
FormB.Show;
FormB.SetFocus;
FormB.OnActivate(Sender); // There is a code in OnActivate event in FormB
end ;
procedure TFormHome.Action3Execute(Sender: TObject);
// Action3 OnExecute event, called from ToolButton3
// This is the desired code to implment in all Action OnExecute event
begin
PR_CreateOpenForm(TFormC); // Fails in the OnActivate event
end;
procedure TFormHome.PR_CreateOpenForm(PClassform : TFormClass);
// This routine should be used to create/open all forms
//
var
vform : TForm;
begin
if Not Assigned(Tform(PClassform)) then
begin
vform := Pclassform.Create(Application);
end;
vform.Parent := PanelHome;
vform.Align := alclient;
vform.BorderIcons := [biSystemMenu];
vform.BorderStyle := bsNone;
vform.Show;
vform.SetFocus;
vform.onActivate(self); // Does not work !! Tried with : vform.Onactivate(nil) - vform.Onactivate(Tform)
end;
end.
FORMA - OnActivate event
procedure TFormA.FormActivate(Sender: TObject);
begin
Edit1.Text := 'content from OnActivate';
end;
FORMB - OnActivate event
procedure TFormB.FormActivate(Sender: TObject);
begin
Edit1.Text := 'content from OnActivate';
end;
FORMC - OnActivate event
procedure TFormC.FormActivate(Sender: TObject);
begin
Edit1.Text := 'content from OnActivate';
end;
Error when calls PR_CreateOpenForm(TFormC)
DEBUG - running step by step reach this event handler error :
procedure TWinControl.MainWndProc(var Message: TMessage);
begin
try
try
WindowProc(Message);
finally
FreeDeviceContexts;
FreeMemoryContexts;
end;
except
Application.HandleException(Self);
end;
end;
Please let me know if I have to provide any other information/code in order to have your suggestions and valuable tips !
Thank you guys !
Update
You asked in a comment
The point is : given a parameter PClassForm of TformClass class, how to check if there is any instance of the such parameter created in the Application ? " ,
You can do this using a function like the FormInstance one below. The Screens object of a VCL application has a Forms property, and you can iterate that, looking to see if one of the forms is a specified class, which is returned as the function's result (which it Nil otherwise). Once you have found the instance, you could of course use a cast to call some specific method of it.
function FormInstance(AClass : TClass) : TForm;
var
i : Integer;
begin
Result := Nil;
for i := 0 to Screen.FormCount - 1 do begin
if Screen.Forms[i].ClassType = AClass then begin
Result := Screen.Forms[i];
Break;
end;
end;
end;
procedure TMyForm.Button1Click(Sender: TObject);
var
F : TForm;
begin
F := FormInstance(TForm2);
if F <> Nil then
Caption := 'Found'
else
Caption := 'Not found';
end;
original answerThe way you've written your q seems to tangle up your actual technical q
vform.OnActivate(??); // That is the issue, how to call this event ?
with a lot of issues which aren't directly related. Rather that try to
invoke the OnActivate handler (If there is one), it may be better
to override the form's Activate procedure to do whatever special handling you want
and then leave it to the code in TForm to decide when to invoke the OnActivate. This is less likely to wrong-foot other form behaviour (like in TScreen).
The code below shows how to do this.
type
TForm1 = class(TForm)
procedure FormActivate(Sender: TObject);
protected
procedure Activate; override;
public
end;
[...]
procedure TForm1.Activate;
begin
inherited;
Caption := Caption + ' called from TForm1.Activate';
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
Caption := 'Activated';
end;
Of course, maybe you could just put the code you want to execute in OnActivate in the OnShow handler instead.
Try change the working OpenDiretorioExecute method to shown code below and tell me if you still get the error. Use vform.OnActivate(Self) inside PR_OpenForm. Please also show the OnActivate event handler for TFormDiretorio.
procedure TFormHome.OpenDiretorioExecute(Sender: TObject);
begin
FormDiretorio:=PR_OpenForm(TFormDiretorio) as TFormDiretorio;
(* if Not Assigned(FormDiretorio) then
begin
FormDiretorio := TFormDiretorio.Create(Self);
FormDiretorio.Parent := PanelCorpo;
FormDiretorio.Align := alclient;
FormDiretorio.BorderIcons := [biSystemMenu];
FormDiretorio.BorderStyle := bsNone;
FormDiretorio.Show;
FormDiretorio.SetFocus;
FormDiretorio.OnActivate(Sender); // In this way , OnActivate works fine
end; *)
end;
Change PR_OpenForm to return vForm. I assume you need the variable FormDiretorio.
The error is in this piece of code:
if Not Assigned(TForm(PClassform)) then
begin
vform := PClassform.Create(Application);
end;
If you look in the source for implementation of Assigned() you will see that it only checks wheter the passed in argument is nil or not. Thus, your code doesn't check for the existence of a form of type PClassForm, as you might think. It only checks whether the parameter PClassForm is nil or not.
In your case Assigned() returns true, the form is not created and subsequently vform contains whatever happens to be on the stack. That it only crashes at the line where you call OnActivate() is just a coincidence. You may have destroyed significant data (and probably have) by accessing the uninitialized vform variable.
To prevent errors like this to become fatal, you should initialize local pointer variables to nil if they might stay uninitialized. You probably also got a compiler warning for this but neglected it.
Already earlier I wanted to ask you where you plan to hold references to the forms that you create, so that you can access them, but I didn't, because it was not your question.
You need to decide on that and then use those references, both to check for existense and to access the forms.
I have a Firemonkey multi device project in Delphi 10 Seattle where the user can get a screen at the start of the app. Here the user needs to fill in 2 fields. But when I click on the edit fields the Virtual Keyboard isn't shown. If I skip this screen at start and call it later then the Virtual Keyboard is shown. This is done in the same way too.
I found sort of a solution:
When i click on the edit fields i call show VirtualKeyboard myself. The only problem is that the cursor isn't shown in the edit field.
Is there a way to place the cursor myself? Or does anyone know how to solve the Virtual Keyboard not showing problem in an other way?
Problem is on both Android and iOS
In the code below you can see the initial form create. The problem is when in ConnectFromProfile method the actCreateNewProfileExecute is called. There it will call a new form. In that form(TfrmProfile) the virtual keyboard isn't shown. I also call this form with another action and then it works fine.
procedure TfrmNocoreDKS.FormCreate(Sender: TObject);
begin
Inherited;
System.SysUtils.FormatSettings.ShortDateFormat := 'dd/mm/yyyy';
CheckPhone;
ConnectfromProfile;
if not Assigned(fProfileAction) then
ConnectDatabase
Else
lstDocuments.Enabled := False;
{$IFDEF ANDROID}
ChangeComboBoxStyle;
{$ENDIF}
end;
procedure TfrmNocoreDKS.ConnectfromProfile;
begin
fdmProfileConnection := TdmConnection.Create(nil);
fdmProfileConnection.OpenProfileDb;
fdmProfileConnection.LoadProfiles;
if fdmProfileConnection.Profiles.Count = 0 then
begin // Createdefault Profile
fProfileAction := actCreateNewProfileExecute;
end
else if fdmProfileConnection.Profiles.Count = 1 then
begin // one profile load connection;
fProfileAction := nil;
fCurrentProfile := fdmProfileConnection.Profiles.Items[0];
end
else
begin // multiple profiles choose connection;
fProfileAction := SelectProfileOnStartUp;
end;
end;
procedure TfrmNocoreDKS.FormShow(Sender: TObject);
begin
if Assigned(fProfileAction) then
fProfileAction(Self);
end;
procedure TfrmNocoreDKS.actCreateNewProfileExecute(Sender: TObject);
var
profilename, databasename, pathname: string;
prf: TfrmProfile;
begin
prf := TfrmProfile.Create(nil);
prf.Data := fdmProfileConnection.Profiles;
prf.ShowModal(
procedure(ModalResult: TModalResult)
begin
if ModalResult = mrOk then
begin
profilename := prf.edtProfilename.Text;
databasename := prf.edtDatabaseName.Text;
{$IFDEF IOS}
pathname := System.IOUtils.TPath.GetDocumentsPath;
{$ENDIF}
{$IFDEF ANDROID}
pathname := System.IOUtils.TPath.GetDocumentsPath;
{$ENDIF}
{$IFDEF WIN32}
pathname := ExtractFilePath(ParamStr(0)) + '\Data';
{$ENDIF}
FDSQLiteBackup1.Database := System.IOUtils.TPath.Combine(pathname,
'default.sqlite3'); // Default Database
FDSQLiteBackup1.DestDatabase := System.IOUtils.TPath.Combine(pathname,
databasename + '.sqlite3');
FDSQLiteBackup1.Backup;
fdmProfileConnection.AddProfile(databasename + '.sqlite3', profilename);
fdmProfileConnection.LoadProfiles;
fCurrentProfile := fdmProfileConnection.Profiles.Items[0];
connectDatabase;
end else
Application.Terminate;
end);
end;
Do not show any additional forms in MainForm.OnCreate/OnShow. Trying this on iOS 9.2 freeze app at "launch screen".
Instead of this, show new form asynchronously, like this:
procedure TForm4.FormShow(Sender: TObject);
begin
TTask.Run(procedure
begin
TThread.Synchronize(nil, procedure // work with visual controls - only throught Synchronize or Queue
begin
Form5:=TForm5.Create(Application);
Form5.ShowModal;
end)
end);
end;
of cource, you can separate this code to external procedures:
procedure ShowMyForm;
begin
Form5:=TForm5.Create(Application);
Form5.ShowModal;
end;
procedure TaskProc;
begin
TThread.Synchronize(nil, ShowMyForm);
end;
procedure TForm4.FormShow(Sender: TObject);
begin
TTask.Run(TaskProc);
end;
========
Another way - do not use any additional forms. Create frame and put it (at runtime) on MainForm with Align = Contents. After all needed actions - hide or release (due to ARC dont forget to set nil to frame variable) this frame.
As my first instance of the question was too broad, I am going to try and reword this so it is more understandable.
I want to be able to change the visibility of a label based on an item in a check box list being checked. I have a loop that goes through my check box list.
procedure TFrmSettings.CheckBoxSelected;
var
i : Integer;
begin
for i := 0 to CblRequiredFields.Items.Count - 1 do
begin
if CblRequiredFields.Checked[i] then
begin
FrmVReg.ReqFields(CblRequiredFields.Items.Strings[i]);
end;
end;
end;
Here is just a part of the ReqFields procedure as it would be too long to put into this Q.
procedure TFrmVReg.ReqFields(ChkStr : String);
begin
if ChkStr = 'Gender' then
begin
lblGenderReq.Visible := True;
end
else
begin
lblGenderReq.Visible := False;
end;
The problem I keep having is I can either only have one label active at one time or have it where a label will not disappear when it is deselected.
I hope I have reworded this to a point that it isn't as broad as the previous question.
If the FrmVReg form exists before the creation of the FrmSettings you can maintain a lisk of key-value pairs (checbox name and label object) in the CblRequiredFields list directly.
The labels visibility can be synchronized with the CblRequiredFieldschecks using the OnClickCheck event of the TCheckListBox object.
procedure TFrmSettings.CblRequiredFieldsClickCheck(Sender: TObject);
begin
TLabel(CblRequiredFields.Items.Objects[CblRequiredFields.ItemIndex]).Visible := CblRequiredFields.Checked[CblRequiredFields.ItemIndex];
end;
procedure TFrmSettings.FormCreate(Sender: TObject);
begin
CblRequiredFields.AddItem('Gender', FrmVReg.lblGenderReq);
CblRequiredFields.AddItem('Age', FrmVReg.lblAgeReq);
. . .
end;
If the above can't be applied, you can modify the ReqFields method like this:
procedure TFrmVReg.ReqFields(ChkStr: String; Checked: Boolean);
begin
if ChkStr = 'Gender' then
lblGenderReq.Visible := Checked
else if ChkStr = 'Age' then
lblAgeReq.Visible := Checked
//else if . . .
end;
... calling it accordingly with its new signature:
for i := 0 to CblRequiredFields.Items.Count - 1 do
FrmVReg.ReqFields(CblRequiredFields.Items.Strings[i], CblRequiredFields.Checked[i]);
I wonder how caught a row of a listview and transform object.
I carry an .xml file and play in a listview , after loading this file you need to double-click in a row, take all of the data line and throw in a LabelEdit , as shown in the code below .
procedure TForm1.LstbxDadosDblClick(Sender: TObject);
begin
if Assigned(TMensagem(LstbxDados.Items.Objects[LstbxDados.ItemIndex])) then
begin
with TMensagem(LstbxDados.Items.Objects[LstbxDados.ItemIndex]) do
begin
EdtPara.Text := Para;
EdtDe.Text := De;
EdtCabecalho.Text := Cabecalho;
EdtCorpo.Text := Corpo;
end;
end;
end;
TMensagem = class
private
FCorpo: String;
FCabecalho: String;
FPara: String;
FDe: String;
public
property Para : String read FPara write FPara;
property De : String read FDe write FDe;
property Cabecalho: String read FCabecalho write FCabecalho;
property Corpo : String read FCorpo write FCorpo;
end;
Many ways to edit an object where the current object can change at any time (like with a double click). Here is one of the easiest: save when the current object changes and save at the very end. Here is a quick and dirty solution.
Add a member to the form or global in the implementation section
FLastMensagem: TMensagem;
May want to initialize to nil on create or initialization (left to you). Now in the event save data when the TMensagem object changes
procedure TForm1.LstbxDadosDblClick(Sender: TObject);
var
LNewMensagem: TMensagem;
begin
LNewMensagem := TMensagem(LstbxDados.Items.Objects[LstbxDados.ItemIndex]));
if Assigned(LNewMensagem) then
begin
// When we switch, capture the dialog before updating it
if Assigned(FMensagem) and (LNewMensagem <> FLastMensagem) then
begin
FLastMensagem.Para := EdtPara.Text;
FLastMensagem.De := EdtDe.Text;
FLastMensagem.Cabecalho := EdtCabecalho.Text;
FLastMensagem.Corpo := EdtCorpo.Text;
end;
EdtPara.Text := LNewMensagem.Para;
EdtDe.Text := LNewMensagem.De;
EdtCabecalho.Text := LNewMensagem.Cabecalho;
EdtCorpo.Text := LNewMensagem.Corpo;
//Set the last dblclicked
FLastMensagem := LNewMensagem
end;
end;
Of course the very last edit needs to be saved, that you can do in say a form close (not sure what your full design is). For example
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Assigned(FLastMensagem) then
begin
FLastMensagem.Para := EdtPara.Text;
FLastMensagem.De := EdtDe.Text;
FLastMensagem.Cabecalho := EdtCabecalho.Text;
FLastMensagem.Corpo := EdtCorpo.Text;
end;
end;