2

I am using an edit box as a round counter. I would like when the text = 5 or 10 for it to show this message then it does some functions. but even when the round is 5 or 10, i never get this message ERoundChange is the OnChange event for the ERound(edit box) ; Any idea why its not working? I assume i am using Self wrong?

{Check if round is 5 or 10}
//-----------------------------------------------------
procedure TBaseGameForm.ERoundChange(Sender: TObject);
//-----------------------------------------------------
begin
 if (self.Text = '5') or (self.Text = '10') then
   begin
      showmessage('checking stats for gryph locations on round: '+self.Text);

    end;
end;

Also I change the round at the beginning of each players turn like so

ERound.Text := inttostr(Strtoint(ERound.Text)Mod 10+1);
Glen Morse
  • 2,437
  • 8
  • 51
  • 102

2 Answers2

3

Since ERoundChange is a method of TBaseGameForm, Self refers to the current instance of TBaseGameForm, that is, to the form, and not the edit box inside it.

Hence, Self.Text is the caption of the form, and not the text inside the edit box. If the edit box is named Edit1, you should do

procedure TBaseGameForm.ERoundChange(Sender: TObject);
begin
  if (Edit1.Text = '5') or (Edit1.Text = '10') then
    ShowMessage('checking stats for gryph locations on round: '+ Edit1.Text);
end;

You could also do

procedure TBaseGameForm.ERoundChange(Sender: TObject);
begin
  if ((Sender as TEdit).Text = '5') or ((Sender as TEdit).Text = '10') then
    ShowMessage('checking stats for gryph locations on round: '+ (Sender as TEdit).Text);
end;

since the control that caused the event is stored in the Sender argument. But since Sender is declared as TObject, you need to cast it to the actual TEdit which it is.

[You could have figured this out yourself. Indeed, the procedure TBaseGameForm.ERoundChange itself has nothing to do with the edit control -- sure, it is assigned to an event of this control, but of course you can assign it to other controls as well, and use it in any other way you like. Hence, by itself, it is only associated with TBaseGameForm, so really, Self couldn't logically refer to anything else.]

Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384
  • ERoundChange is not a class method it is just a simple method ;o) – Sir Rufo Nov 18 '12 at 17:10
  • Thanks that was exactly it! is there an advantage to doing it between the two? if not ill take the top one as its less code :D – Glen Morse Nov 18 '12 at 17:10
  • @GlenMorse: The obvious advantage of the last version is that you can assign it to *different* edit controls, and it will check the text in the edit control that was just changed. But if you only have one such edit control, there is no difference. In fact, the first version is safer, because then you can call `ERoundChange(AnythingYouLike)` without causing havoc. [Otherwise, you *have* to call it `ERoundChange(Edit1)`.] – Andreas Rejbrand Nov 18 '12 at 17:12
  • I never like repetition in code, so I'd not be content with code that writes `(Sender as TEdit)` more than once. But that said, I'd also always prefer the version that keys off the `Sender` rather than building in a reference to a specific edit control. – David Heffernan Nov 18 '12 at 17:20
  • @David: Of course you can do that. Your answer gives an explicit example of that. – Andreas Rejbrand Nov 18 '12 at 17:21
3

That method is an instance method of the form and so Self.Text refers to the text, or caption, of the form. You need to use

(Sender as TEdit).Text

instead.

Although, to avoid duplication you should use a local variable to hold the edit control reference:

procedure TBaseGameForm.ERoundChange(Sender: TObject);
var
  Edit: TEdit;
begin
  Edit := (Sender as TEdit);
  if (Edit.Text = '5') or (Edit.Text = '10') then
    ShowMessage('checking stats for gryph locations on round: ' + Edit.Text);
end;
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Just for the record. If you choose this approach, and if you want to call the function manually, you have to pass the correct `TEdit` control as the argument (`Sender`); you cannot do `ERoundChange(nil)`, `ERoundChange(Self)`, or something like that. – Andreas Rejbrand Nov 18 '12 at 17:19
  • @AndreasRejbrand You could have said the same in your own answer. – David Heffernan Nov 18 '12 at 17:21
  • I did, actually. (In a comment, just like here.) – Andreas Rejbrand Nov 18 '12 at 17:22
  • 3
    @AndreasRejbrand The `Sender` parameter often feels unsatisfactory to me. I don't like the fact that it is untyped. As for calling event handlers from code, I don't very much care for that. I'd rather write a separate method which is then called from the event handler. If you follow this policy you can assume that event handlers are always passed a meaningful `Sender`. – David Heffernan Nov 18 '12 at 17:27