views:

163

answers:

4

The below code is in OnTimer event. If items from 2 list boxes are not matching - ShowMessage. I need to show the message only once, but because the timer is running, the message keeps popping up at the timer's set interval. I tried disabling the timer after ShowMessage line but then the message would even show.

for i := 0 to ListBox2.Items.Count - 1 do begin
  p := ListBox1.Items.IndexOf(ListBox2.Items[i]);
  if p = -1 then
    ShowMessage('not matching');
end;

Thanks.

+2  A: 

Try make another variable (type example Boolean) and keep it False if the message hasn't shown yet, True when it shows, and change the condition to something like this:

if (p = -1) and not messageShown then ...

Remember to change messageShown to True after the message appears the first time.

Rin
Thanks. I am new to programming but I can't get this to work. This is what I have:<pre>if p = -1 then ShowMessage('not matching'); msgShown := 1; if p = -1 and msgShown := 1 then timer2.Enabled := false;</pre>But it's saying "THEN' expected but ':=' found"
emC
When u check value in `if` use `=` instead `:=` ;) And you should have only one `if` which check `p = -1` AND `msgShown` at the same time :)Anyway, I am not delphi programmer... it was years ago :)
Rin
A: 

Was the line disabling the timer inside the if block or did it run in every iteration of the loop? If it were me, I'd set a flag indicating that the message needs to be show, then exit the loop. After the loop I'd check if the message should be shown and, if so, both show the message and turn off the timer. Presumably the timer gets reset when the items in the list boxes change so that the check will run again.

Caveat: I'm not a Delphi programmer; I'm only speaking in general terms of how I would structure it. If what I've said makes no sense from a Delphi perspective, comment and I'll remove my answer.

tvanfosson
the line disabling the timer was inside the if block. I understand your suggestion I just have try figure out how to write the code - I am new to programming...thanks
emC
+1  A: 

Another possible solution is this:

  timer1.Enabled := false; // <---

  for i := 0 to ListBox2.Items.Count - 1 do begin
    p := ListBox1.Items.IndexOf(ListBox2.Items[i]);
    if p = -1 then
    begin
      ShowMessage('not matching');
      exit;  // <---
    end;
  end;

  timer1.Enabled := true; // <---

If the lists don't match, that code shows the message and disables the timer.
Of course in that case you'll have to enabled it from some other routine.

Nick D
The timer is enabled on FormActivate so it is constantly running. I tried your code but it still causes the same problem.
emC
@Nick D: you forgot try..finally ;)
inzKulozik
+5  A: 

i suspect what you did was put the enabled := false after the message box. put the enabled := false before the message box and it should work:

var
  i : integer;
  p : integer;

begin

  for i := 0 to ListBox2.Items.Count - 1 do begin
    p := ListBox1.Items.IndexOf(ListBox2.Items[i]);
    if p = -1 then begin
      timer1.Enabled := false;
      ShowMessage('not matching');
      break;
    end;
  end;

best regards, don

Don Dickinson
thanks this worked!
emC
And the reason for switching the order is that when `ShowMessage` is active (or the program is in any other modal state), messages are processed, so the OS continues to add new `wm_Timer` messages to the thread's message queue.
Rob Kennedy
@Rob Kennedy, that's why we should disable the timer at the beginning of the procedure.
Nick D