Jak wymusić zakończenie funkcji obsługi zdarzenia

0

Mam taki problem (programuję w C++Builder 6). Na formularzu są dwa przyciski. Każdy z nich ma swoją funkcję obsługi zdarzenia OnClick. Klikam przycisk Button1 i rozpoczyna się jego funkcja obsługi zdarzenia.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  while(1)
    Application->ProcessMessages();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
  int i = 0;
}
//---------------------------------------------------------------------------

W jaki sposób mogę wstrzymać obsługę innych zdarzeń dopóki nie zostanie zakończona wywołana funkcja, z jednoczesnym przetwarzaniem komunikatów (za pomocą Application->ProcessMessages()). Czy jest jakiś sposób na wymuszenie zakończenia rozpoczętych już funkcji obsługi zdarzeń?

Poniższy kod podałem jako przykład funkcji, która trwa na tyle długo aby użytkownik mógł wykonać w tym czasie inne akcje. Wiem, że funkcja Button1Click się nie zakończy

  while(1)
    Application->ProcessMessages();

Z góry dziękuję za pomoc

0
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Button1->Enabled = false ; // Zabezpieczenie przed
                            // ponownym wykonaniem kodu
                            // z Button1Click(..)
                            // jesli nie zostal zakonczony
  while(!Button1->Enabled)
  {
    Application->ProcessMessages();
  }

  ShowMessage("Koniec - Button1Click .");


}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{

  Button1->Enabled = true ;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
   Button1->Enabled = true ; // konczymy Button1Click
                             // jesli zamykamy aplikacje
   ShowMessage("Close") ;
}
//---------------------------------------------------------------------------
0

Sprytne rozwiązanie, niestety nie o to mi chodziło.

Po pierwsze - nie chcę blokować żadnych funkcji obsługi zdarzeń, wręcz muszą być one wykonane, tyle że w kolejności w jakiej zostały wywołane (i po zakończeniu poprzednich funkcji).
Po drugie - kontrolek (nie tylko klasy TButton) posiadających swoje zdarzenia jest bardzo dużo i warunek na blokowanie funkcji byłby skomplikowany.
Po trzecie - nie chodzi tylko o zdarzenie OnClick, ale także OnEnter, OnExit i.in.

Byłbym bardzo wdzięczny za rozwiązanie problemu.

0

Najlepiej zrobić to wielowątkowo

0

Po drugie - kontrolek (nie tylko klasy TButton) posiadających swoje zdarzenia jest bardzo dużo i warunek na blokowanie funkcji byłby skomplikowany.
Po trzecie - nie chodzi tylko o zdarzenie OnClick, ale także OnEnter, OnExit i.in.

Po drugie , nie szkodzi , można łatwo rozpoznać która kontrolka jest "nadawcą komunikatu"
Po trzecie - reszta zdarzeń może być obsługiwana tak samo .(Flagi np. globalne stanu )
to że wykorzystałem zmienne obiektów TButton (Enabled) nic nie znaczy ,
może to być zmienna globalna ustawiona przez zdarzenie np. OnEnter .

Po czwarte - wykorzystanie wątków może byc podobnie skomplikowane jak obsługa
komunikatów .
To zależy od kodu , jeśli chcesz mieć całkowitą kontrolę nad niezależnym wykonaniem
funkcji musisz i tak napisać kod który zasygnalizuje ich stan a to naprawdę jest podobnie zakręcone .

Tu możesz np. wywołać wielokrotnie OnClick :

int stos_wywolania = 0 ;
bool*stop[100] ={NULL} ;

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  bool stop_local = false ;
  stop[stos_wywolania] = &stop_local ;
  stos_wywolania++ ;

  int local_id = stos_wywolania ;
  ShowMessage(String("Wywolano OnClick raz:")+stos_wywolania);
  while(!stop_local)
  {
    Application->ProcessMessages();
  }

  ShowMessage("Koniec - Button1Click nr" + String(local_id)  );


}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{

  ShowMessage(String("Usunieto wywolanie OnClick :")+(stos_wywolania));
  stos_wywolania --   ;
  *stop[stos_wywolania] = true ;


}
//---------------------------------------------------------------------------

Uwaga , nie ma kontroli przekroczenia odwołań ( <0 ) stanu "stosu_wywolania" .
Trzeba "ręcznie kontrolować" , jeśli Fun została wywołana 2x , nie wolno jej kończyć 3x ,
ale to tylko przykład ....

1 użytkowników online, w tym zalogowanych: 0, gości: 1