Events eines Formulars blockieren
-
Hi φolks!
Ich habe ein Main-Formular in dem ich eine Datenbankverbindung aufbaue, dass dauert eine Weile. Wärenddessen zeige ich ein kleines Infofenster mit einem TAnimate an (Infofenster->Show();), was den User darauf hinweist, das er sich ein klein wenig gedulden soll.
Mein Problem ist nun, wenn der User trotz des agezeigten Infofensters wie verrückt auf der Mainform rumklickt, merkt sich das das Main-Fenster und führt die Klicks hinterher aus ... Das will ich nicht. ShowModal() hilft mir hier auch nicht weiter. Wie kann ich ein Formular gegen Mausklicks sperren, gibt es da vielleicht eine Windows-Message?
F98
-
Ganz einfach
In jedem OnKlick-Event:if(Infofenster->Visible) return;
MfG
xy
-
ShowModal statt Show!?
Ansonsten einfach die Form disablen, den langwierigen Code starten und dann die die Form wieder enablen.
-
Oder:
Nur alle klickbaren Elemente am Anfang disablen, und erst wenn die Aktualisierung fertig ist und das Infofenster weg ist, dann erst enablen. Da kann der Benutzer klicken, was er will...MfG
xy
-
@xy:
Das artet in Sysiphusarbeit aus.
Jansen schrieb:
Ansonsten einfach die Form disablen ...
Wie meinst Du das genau?
-
Siehe TForm::Enabled.
Und von wegen in Arbeit ausarten: schon mal was von Schleifen gehört?
Einfach über die Elemente der Form iterieren, nach TControl casten und disablen. Gegenüber dem Disablen der Form selbst hat der User hier auch ein visuelles Feedback (ausgegraute Beschriftungen etc.).Aber üblicherweise dürfte ShowModal das Mittel der Wahl sein.
-
hallo,
wenn du eh mit einer datenbank arbeitest, gibt es da eine methode EnableControls() -> DisableControls und zwar ist das eine methode von
TQuery, TTable, etc. Das wäre nur ein aufruf und so macht man das normal,
wenn man will, das während längerer berechnungen nicht auf den controls
rumgehakt werden will, schau mal in der hilfe unter den o. g. namen nach.ansonsten: Warum geht es mit modal nicht, was für ein grund spricht denn
da dagegen?mfg
murph
-
TDataSet::EnableControls/DisableControls wirken nur auf die mit dem jeweiligen DatSet verbundenen Controls (DBGrid etc.), nicht auf "normale" Buttons usw.
Ausserdem dienen sie nur zum De/Aktivieren der Anzeige aus Performancegründen, Benutzereingaben in diesen Controls werden hingegen weiterhin verarbeitet.
-
Ich denke ich weiss, warum ShowModal() nicht läuft
Infofenster->Show(); //Der lange dauernde Code Infofenster->Hide();
Das lässt sich über ShowModal() nicht machen, da der den Code ja "anhält" und auf das Fenster wartet.
-
-=]xXx[=- schrieb:
... Das lässt sich über ShowModal() nicht machen, da der den Code ja "anhält" und auf das Fenster wartet.
Das ist der springende Punkt.
-
Dafür gibt's TThread.
Vielleicht gehst du ja auch mal auf die anderen Antworten ein?
-
Yo. Auf Grund Deines Tipps mit dem TForm::Enabled habe ich mich düster entsonnen, dass ich sowas schonmal irgendwo verwendet hatte, allerdings in einem etwas anderem Zusammenhang:
- 1 Mainform
- x MDI-Childs die von einer Basisform mit einem Messagehandler abgelitten wurdenvon der Mainform konnte man dann per Message die einzelnen Fenster für die Eingabe sperren:
// MDI Fenster sperren for (i=MDIChildCount-1; i>=0; i--) { PostMessage(MDIChildren[i]->Handle, WM_LOCK_WINDOW, 0, 0); } ... // MDI Fenster wieder freischalten for (i=MDIChildCount-1; i>=0; i--) { PostMessage(MDIChildren[i]->Handle, WM_UNLOCK_WINDOW, 0, 0); }
Und hier noch der Quellcode für das Basis MDI-Fenster:
*.h
#ifndef UBasisMDIFormH #define UBasisMDIFormH //--------------------------------------------------------------------------- #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> //--------------------------------------------------------------------------- class TfrmBasisMDIForm : public TForm { __published: // Von der IDE verwaltete Komponenten private: protected: void __fastcall LockWindow(TMessage M); void __fastcall UnLockWindow(TMessage M); public: __fastcall TfrmBasisMDIForm(TComponent* Owner); virtual __fastcall ~TfrmBasisMDIForm(); BEGIN_MESSAGE_MAP VCL_MESSAGE_HANDLER(WM_LOCK_WINDOW, TMessage, LockWindow); VCL_MESSAGE_HANDLER(WM_UNLOCK_WINDOW, TMessage, UnLockWindow); END_MESSAGE_MAP(TForm) }; //--------------------------------------------------------------------------- extern PACKAGE TfrmBasisMDIForm *frmBasisMDIForm; //--------------------------------------------------------------------------- #endif
*.cpp
//--------------------------------------------------------------------------- // // Basisform für alle MDI-Cilds // // beinhaltet den Basis-Messagehandler. Alle weiteren evtl. VCL-Message- // Handler in untergeordneten MDI-Forms sollten wie folgt integriert werden: // // BEGIN_MESSAGE_MAP // VCL_MESSAGE_HANDLER( ... ); // END_MESSAGE_MAP(TfrmBasisMDIForm) // //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "UBasisMDIForm.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TfrmBasisMDIForm *frmBasisMDIForm; //--------------------------------------------------------------------------- __fastcall TfrmBasisMDIForm::TfrmBasisMDIForm(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- __fastcall TfrmBasisMDIForm::~TfrmBasisMDIForm() { } //--------------------------------------------------------------------------- void __fastcall TfrmBasisMDIForm::LockWindow(TMessage M) { TForm::Dispatch(&M); this->WindowState = wsMinimized; this->Enabled = false; // Eingaben auf der Form sperren } //--------------------------------------------------------------------------- void __fastcall TfrmBasisMDIForm::UnLockWindow(TMessage M) { TForm::Dispatch(&M); this->WindowState = wsNormal; this->Enabled = true; }
Zurück zu eigentlichen Thema:
Die Sache ist nun die, dass
this->Enabled = false;
keine Auswikrung auf die Sperrung der MainForm hat. Das kleine "Bitte warten Fenster" poppt auf. Wenn man aber jetzt in der Mainform rumklickt werden die Events in eine Queue gelagert und nach ausführen des Datenbankconnects trotzdem ausgeführt ... Hm.
-
F98 schrieb:
this->Enabled = false;
keine Auswikrung auf die Sperrung der MainForm hat. Das kleine "Bitte warten Fenster" poppt auf. Wenn man aber jetzt in der Mainform rumklickt werden die Events in eine Queue gelagert und nach ausführen des Datenbankconnects trotzdem ausgeführt ... Hm.
Und was ist mit:
FormName->Enabled = false;
Mfg
xy
-
@xy:
this == Formname
-
Das ist deine Hoffnung/Vermutung? Hast du's trotzdem mal mit dem Formnamen probiert? An Welcher Stelle genau setzt du die Enabled-Property?
Und ist dein aktuelles Programm, bei dem du die Form sperren willst, nun ein MDI- oder SDI-Projekt?
-
Jansen schrieb:
Das ist deine Hoffnung/Vermutung? Hast du's trotzdem mal mit dem Formnamen probiert? An Welcher Stelle genau setzt du die Enabled-Property?
Und ist dein aktuelles Programm, bei dem du die Form sperren willst, nun ein MDI- oder SDI-Projekt?1. Meine Angabe ist Gewißheit: ZeigerAdr von this == ZeigerAdr von FormName
2. ja
3. direkt vor dem DB Connect.
4. SDI (Ich wußte das mein MDI-Einwurf von oben Verwirrung stiftet)
-
F98 schrieb:
this->Enabled = false;
keine Auswikrung auf die Sperrung der MainForm hat. Das kleine "Bitte warten Fenster" poppt auf. Wenn man aber jetzt in der Mainform rumklickt werden die Events in eine Queue gelagert und nach ausführen des Datenbankconnects trotzdem ausgeführt ... Hm.
Funktioniert es denn, wenn Du die einzelnen klickbaren Elemente disablest?
Versuchswert.MfG
xy
-
Ich deaktiviere jetzt im MainFormular in der Eregnismethode OnDeactivate das Panel wo ich die ganzen Elemente drauf habe. das funktioniert. In OnActivate wir dann das Panel wieder aktiviert.
Funktioniert also jetzt soweit.
-
Muss mit der Form genauso funktionieren.
Naja, wenn du mal Zeit hast, das etwas professioneller zu gestalten, dann solltest du nochmal über TThread + ShowModal nachdenken, oder zumindest die Variante mit dem disablen der einzelnen Controls durchspielen.
Denn im Moment verwirrst du den Benutzer, indem du ihm Controls präsentierst, die klick-bar aussehen, es aber nicht sind. Das ist schlechtes GUI-Design.
-
Du hast recht. Aber für meine Zwecke reicht es aus.
Ω