TComboBox-Objekt soll DropDown ausführen bei KeyUp mit Key == VK_RETURN, realisierbar? [gelöst]
-
Nimm besser OnKeyPress, dann funktioniert das wie gewünscht. Frag mich nicht warum, aber OnKeyUp und OnKeyDown zeigen manschmal ein recht seltsames Verhalten...
Du könstest Dir auch das if-Gedingse sparen (zumindest in der ersten Variante):
vCmbBx->DroppedDown = !vCmbBx->DroppedDown;
-
Joe_M. schrieb:
Nimm besser OnKeyPress, dann funktioniert das wie gewünscht.
Dann kann ich aber TShiftState nicht mehr abfragen!?!
Joe_M. schrieb:
Frag mich nicht warum, aber OnKeyUp und OnKeyDown zeigen manschmal ein recht seltsames Verhalten...
Vielleicht ist das des Rätsels Lösung:
BDS2006-Hilfe schrieb:
Eine Anwendung erhält für alle Tasten, die vom Anwender gedrückt werden, Windows-WM_KEYDOWN-Botschaften. Diese Botschaften lösen das Erignis OnKeyDown indirekt aus. Wenn Sie Key auf 0 setzen, verhindern Sie dadurch nur eine weitere Verarbeitung dieser Botschaft. Für Tasten, die Zeichen erzeugen, erzeugt Windows auch WM_CHAR-Botschaften. Zu dem Zeitpunkt, an dem Ihr OnKeyDown-Ereignis ausgelöst wird, befindet sich die WM_CHAR-Botschaft für die Taste bereits in der Botschaftswarteschlange. Das Setzen von Key auf 0 stoppt die Botschaft nicht, daher wird das Ereignis OnKeyPress ausgelöst. Sie müssen Key auf #0, setzen, um zu verhindern, dass das Steuerelement die WM_CHAR-Botschaft abfängt.
Diese Art des Organisierens von Tastenverarbeitungen hat Vorteile. Quelltext, der sich nur mit Zeichen, einschließlich Zeichen wie #13 Zeilenschaltung, #3 für Strg+C usw., befasst, sollte in das Ereignis OnKeyPress aufgenommen werden. Quelltext, der sich mit Tasten befasst, die keine Zeichen erzeugen, sollte in das Ereignis OnKeyDown aufgenommen werden.
Wie setze ich denn Key auf #0?
Key= #0;
erzeugt [C++ Fehler] XYZ.cpp(132): E2206 Ungültiges char-Zeichen '#' (0x23)...?
Joe_M. schrieb:
Du könstest Dir auch das if-Gedingse sparen [...]
Yes, ich weiß, Danke.
-
Hallo
Key = 0;
Das # ist ein Fragment aus der Delphi-Syntax.
bis bald
akari
-
Hmmm, das hatten wir schon (siehe meinen vorletzten Post), trotzdem Danke für die Antwort.
Wenn ich Alles hier zusammenfasse, muss ich wohl beide Ereignisse (OnKeyDown UND OnKeyPress) nutzen, um die gewünschte Funktionalität zu erreichen:
* OnKeyDown: Shift + Enter = nächstes Steuerelement
* OnKeyPress: Enter = Öffnen / Schliessen der DropDown-ListeIch teste es mal so.
-
Das hier funktioniert keinesfalls:
void __fastcall TFormXYZ::ComboBoxKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if(Key == VK_RETURN && Shift.Contains(ssShift)){ Key= 0; TWinControl* NextCompo= NULL; NextCompo= FindNextControl(ActiveControl, true, true, false); NextCompo->SetFocus(); } // der Focus wird auf die nächste Komponente gesetzt, ABER: die DropDown-Liste der ComboBox öffnet sich trotz Key= 0 } void __fastcall TFormXYZ::ComboBoxKeyPress(TObject *Sender, char &Key) { Key= 0; TComboBox* vCmbBx= static_cast<TComboBox*>(Sender); vCmbBx->DroppedDown= !vCmbBx->DroppedDown; // die DropDown-Liste öffnet sich, ABER: wenn sie eigentlich geschlossen werden sollte, öffnet sie sich sofort wieder }
Bisher ist und bleibt die Einzige funktionierende Version mein 2. Codebeispiel aus meinem 4. Post hier...
-
Die Problematik liegt ganz einfach in 2 Dingen:
1. dass die TComboBox-Komponente auf die Enter-Taste schon von allein reagiert, sobald die DropDown-Liste eingezeigt wird, was nirgendwo bisher von mir nachzulesen war, aber eindeutig reproduziert werden kann.
2. setzt man im OnKeyDown Key= 0, wird die WM_CHAR-Botschaft trotzdem an die ComboBox weitergeleitet.Und schon steht man da und rätselt...
-
Hmpf... Das ist ja ein Murks... Ich bekomme es aucb nicht ohne Zwischenvariable hin.
Ich hab die Tag-Eigenschaft verwendet. Jetzt weiß ich zumindest, wofür die gut ist.
Das Setzen von Key = 0 bringt irgendwie rein gar nichts, kann man also auch getrost weglassen.
void __fastcall TForm1::ComboBox1KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { if (Key == VK_RETURN) { ComboBox1->DroppedDown = !ComboBox1->Tag; } } //--------------------------------------------------------------------------- void __fastcall TForm1::ComboBox1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if (Key == VK_RETURN) { ComboBox1->Tag = ComboBox1->DroppedDown; } } //---------------------------------------------------------------------------
Einzige andere Möglichkeit, die ich noch sehen würde, wäre die WM_CHAR-Botschaft abzufangen.
-
Joe_M. schrieb:
[...]Ich hab die Tag-Eigenschaft verwendet. Jetzt weiß ich zumindest, wofür die gut ist.
[...]
Ich verwende diese Eigenschaft desöfteren. Z.B. habe ich in einer Anwendung ein Formular mit zahlreichen CheckBox-Komponenten und dazugehörigen ComboBox-Komponenten (zur Entwurfszeit auf dem Formular platziert). Nun soll eine ComboBox aktiviert werden, wenn ihre CheckBox gesetzt wurde. Damit der Code übersichtlich bleibt, soll das Ganze in nur einer Methode für alle CheckBox-Kompo's erfolgen. Also gebe ich jeder CheckBox ihrer zugehörigen ComboBox dasselbe Tag. In der Methode caste ich den Sender (CheckBox), hole mir den Tag-Wert, durchlaufe dann in einer Schleife alle Form-Komponenten und versuche sie als ComboBox zu casten. Gelingt der cast, kann ich die Tags vergleichen und wenn sie gleich sind, kann ich die ComboBox aktivieren. Fertig.
Joe_M. schrieb:
[...] Das Setzen von Key = 0 bringt irgendwie rein gar nichts, kann man also auch getrost weglassen. [...]
Das meine ich! Ich vermute deshalb immernoch, dass der folgende Satz aus der Hilfe nicht einfach mit akari's Erklärung (Zitat: Das # ist ein Fragment aus der Delphi-Syntax.) abgetan ist:
BDS2006-Hilfe schrieb:
[...] Das Setzen von Key auf 0 stoppt die Botschaft nicht [...]. Sie müssen Key auf #0, setzen, um zu verhindern, dass das Steuerelement die WM_CHAR-Botschaft abfängt.
Joe_M. schrieb:
[...]
void __fastcall TForm1::ComboBox1KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { if (Key == VK_RETURN) { ComboBox1->DroppedDown = !ComboBox1->Tag; } } //--------------------------------------------------------------------------- void __fastcall TForm1::ComboBox1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if (Key == VK_RETURN) { ComboBox1->Tag = ComboBox1->DroppedDown; } } //---------------------------------------------------------------------------
Warum nicht so:
void __fastcall TForm1::ComboBox1KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { if(Key == VK_RETURN) ComboBox1->DroppedDown= !ComboBox1->Tag; } //--------------------------------------------------------------------------- void __fastcall TForm1::ComboBox1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if(Key == VK_RETURN) ComboBox1->Tag= ComboBox1->DroppedDown; } //---------------------------------------------------------------------------
???
Wenn man sich schon für übersichtlichen Code einsetzt...Joe_M. schrieb:
[...]Einzige andere Möglichkeit, die ich noch sehen würde, wäre die WM_CHAR-Botschaft abzufangen.
Ja, das würde gehen... das wäre aber das berühmte "mit Kanonen auf Spatzen schiessen".
-
Kolumbus schrieb:
Warum nicht so:???
...
Wenn man sich schon für übersichtlichen Code einsetzt...Na ja, da waren noch ein paar mehr Anweisungen zum Testen drin... Außerdem würde ich höchstenfalls die Klammern weglassen, aber nicht den Vergleich und die Anweisung in die gleiche Zeile schreiben. Reine Geschmackssache...
-
Ja genau, das macht ja Jeder, wie es ihm am Besten passt.