Gibt es eine Möglichjkeit festzustellen, welches Objekt gerade den Focus hat?
-
-
Wenn man nicht mehr weiter weiß -- schaut man in den R-BASIC Code. - Einfache und oft clevere Lösungsidee siehe unten
Das Objekt, dass den aktuellen Focus hat, befindet sich am Ende des sogenannten Focus-Pfads. Jedes Objekt, beginnend bei Application, verweist auf eines seiner Children, das die nächste Stufe im Focus_Pfad ist **. Am Ende steht das Objekt, dass den Focus hat.
Die Grundidee ist, beim Application-Objekt anzufangen und sich rekursiv mit MSG_META_GET_FOCUS_EXCL sich das nächst Objekt im Focus-Pfad geben zu lassen. Wenn das keine Childrern hat - oder einen Null-Optr liefert - , ist das aktuelle Focus-Objekt gefunden. R-BASIC behandelt natürlich alle denkbaren Fälle, deswegen sieht es etwas komplexer aus. Alles unterhalb Zeile 34 ist deshalb für dich wahrscheinlich nicht relevant.
Code
Display More/*--------------------- ToolFindFocus -------------------------------* * Aufgabe: Aktuelles Focus-Objekt finden * Return NULL wenn Focus nicht existiert oder nicht gefunden werden kann * Ein Problemfall war: Number Objkete können intern den Focus haben, * MSG_META_GET_FOCUS_EXCL liefert aber den optr des TEXT-Objekts, dass * vom Number-Objekt intern erzeugt wird * -> das ist kein GEN und kein BASIC Objekt -> deswegen Abfrage *----------------------------------------------------------------------*/ optr ToolFindFocus(RuntimeControlStruct *runControl) { optr obj, focusObj = 0; int numChildren; ObjectVariable objectVar; Boolean ok; @call application::MSG_META_GET_FOCUS_EXCL(&obj); numChildren = @call application::MSG_GEN_COUNT_CHILDREN(); while (obj && numChildren) { focusObj = obj; numChildren = @call obj::MSG_GEN_COUNT_CHILDREN(); ok = @call obj::MSG_META_GET_FOCUS_EXCL(&obj); if (!ok) return focusObj; // savety: keine Focus-Node, kann aber den Focus haben (?) // Prüfen ob es ein BASIC-Objekt ist. Wenn nicht: Abbruch ExecObjectOptrToObjectVariable(runControl, focusObj, &objectVar); if ( objectVar.objReferenz.memChunk == 0 ) return NULL; if ( objectVar.objReferenz.objChunk == 0 ) return NULL; if ( objectVar.objType == BASIC_OBJECT_INTERNAL ) return NULL; } // Checken, ob es ein View ist. Dann mit dem Content weiter machen, ansonsten Focus gefunden ExecObjectOptrToObjectVariable(runControl, focusObj, &objectVar); if ( (objectVar.objType & ~BAS_OBJ_IS_SUBCLASSED_OBJECT) != BASIC_OBJECT_VIEW ) { return focusObj; } obj = @call focusObj::MSG_GEN_VIEW_GET_CONTENT(); if ( obj == 0 ) { return focusObj; // View hat kein Content -> ist selbst Focus-Objekt } focusObj = obj; // content hat den Focus // Jetzt den VIS-Tree bearbeiten numChildren = @call obj::MSG_VIS_COUNT_CHILDREN(); while (obj && numChildren) { focusObj = obj; numChildren = @call obj::MSG_VIS_COUNT_CHILDREN(); ok= @call obj::MSG_META_GET_FOCUS_EXCL(&obj); if (!ok) return focusObj; // keine Focus-Node, kann aber den Focus haben // Prüfen ob es ein BASIC-Objekt ist. Wenn nicht: Abbruch ExecObjectOptrToObjectVariable(runControl, focusObj, &objectVar); if ( objectVar.objReferenz.memChunk == 0 ) return NULL; if ( objectVar.objReferenz.objChunk == 0 ) return NULL; if ( objectVar.objType == BASIC_OBJECT_INTERNAL ) return NULL; } return focusObj; }
Die einfache Variante wäre, wenn du eine begrenzte Anzahl von Objekten hast, die in Frage kommen, bei diesen Objekten MSG_..._GAINED_FOCUS_EXCL() und sich in einer globalen Variablen zu merken, welches das aktuelle Objekt ist. MSG_LOST_FOCUS_EXCL() muss dann die globale Variable auf Null setzen, als Kennung für den Spezialfall, dass kein Objekt den Focus hat.
Gruß
Rainer** intern werden mache Objekt, die nicht den Focus haben könne, übersprungen.
-
Das habe ich wohl verstanden, denke ich.
Aber eigentlich habe ich angenommen, dass das System weiß, wo sich der Focus gerade befindet, und angenommen, dass man diese Info direkt bekommen kann.
-
So wie ich das verstanden habe, werden die Tastaturereignisse einfach den Focuspfad entlang geschickt. Das wird wohl irgendwelche Vorteile haben.
Nachtrag: z.B. kannst du so auf Application-Ebene (oder auf jeder andere Focus-Node Ebene) MSG_META_KBD_CHAR überschreiben, ohne das aktuelle Focus-Objekt zu kennen.
-
Mir fällt da noch diese Message ein: MSG_VIS_FUP_QUERY_FOCUS_EXCL.
Viele Grüße,
Falk \\ blueway.Softworks -
Ich habe es jetzt so lösen können:
Code@method GCalcInteractionClass, MSG_META_KBD_CHAR { EventHandle event; if(character==-229) //Esc { event = @record null:: MSG_GEN_GUP_INTERACTION_COMMAND( IC_DISMISS); @call GCalcApp::MSG_META_SEND_CLASSED_EVENT(event, TO_FOCUS); } }
Festgepinnte Menüs gehen dabei noch nicht, komisch
-
Ja, das sieht nach der korrekten Lösung nach GEOS-Art aus!
-
Festgepinnte Menüs gehen dabei noch nicht, komisch
Ich vermute, Menüs haben nicht selbst den Focus, sondern eins ihrer Children. Bin aber nicht sicher. Und habe keine Idee ...
-
Laufen festgepinnte Menüs nicht immer automatisch in einem eigenen UI-Thread? (Damit sie sich auch dann neu zeichnen können, wenn die eigentliche Applikation beschäftigt ist.)
-
Und das würde bedeuten?
-
Ich vermute, Menüs haben nicht selbst den Focus, sondern eins ihrer Children. Bin aber nicht sicher. Und habe keine Idee ...
Das würde erklären, warum sie ihre Titelzeile farblich nicht ändern (sondern wie ein Dialogfenster aussehen , die den Focus nicht haben).
Das festgepinnte Menü reagiert auch nicht, wenn ich ihm direkt den Befehl zum Schließen sende.
-
Das festgepinnte Menü reagiert auch nicht, wenn ich ihm direkt den Befehl zum Schließen sende.
Analog reagieren die Menü-Einträge auch nicht, wen ich ihnen den Befehl zum Öffnen sende. Ich hab das jetzt so gelöst, dass ich die Navigation-Char-Sequenz simuliere und an die Application sende.
Die Menüs sollten nicht in einem eigenen Thread laufen, sonder im ganz normalen UI-Thread. Und selbst wenn, hätte das keien Auswirkugen auf die Kommandos, die man ihnen senden muss.
Rainer
-
Tastenkürzel-Rätsel:
Öffnet in z.B. GeoWrite das Menü für Zeichen (Character) und pinnt es fest. Wer schafft es, das Menü nur über die Tastatur zu schließen (F3 ist unfair
),
oder einen Menüpunkt anzuwählen?
Ich bin gespannt, weil ich selber keine Lösung habe.
-
Tastenkürzel-Rätsel:
Öffnet in z.B. GeoWrite das Menü für Zeichen (Character) und pinnt es fest. Wer schafft es, das Menü nur über die Tastatur zu schließen (F3 ist unfair
),
oder einen Menüpunkt anzuwählen?
Ich bin gespannt, weil ich selber keine Lösung habe.
Es geht nur wenn du den Fensterbutton mit der Maus anklickst und dann ALT-S ! Keine Maus nicht möglich ,man kann die Pinbaren Menüs in Einstellungen "UI konfigurieren" deaktivieren.
Das Fenster hat ja kein Focus !
von Nico
-
Danke für deinen Versuch, aber es geht ja darum, dass man auch navigieren können muss, wenn die Maus plötzlich nicht zur Verfügung steht.
-
Danke für deinen Versuch, aber es geht ja darum, dass man auch navigieren können muss, wenn die Maus plötzlich nicht zur Verfügung steht.
Navigieren geht ja über die Navigations-Chars (Unterstrichene Buchstaben), auch wenn das Menü angepinnt ist kann man es erreichen. Anpinnen geht mit der Tastatur mit Leertaste. Nur Schließen habe ich via Tastatur nicht hinbekommen. Ich fürchte fast, das ist ein Problem, dass auf Systemebene gelöst werden muss.
Rainer
-
Nach dem Anpinnen ist bei mir ein Weiterkommen über die unterstrichenen Buchstaben nicht möglich.
-
Nach dem Anpinnen ist bei mir ein Weiterkommen über die unterstrichenen Buchstaben nicht möglich.
Man muss wieder die ganze Sequenz durchgehen. Also in GeoWrite für Optionen->Werkzeuge Zeigen -> Funktionsleiste: Alt-O - W - F. Das geht auch, wenn das Menü angepinnt ist. Nur das gepinnte Mneü schließen scheint prinzipiell nicht zu gehen.
Rainer
-
Was eventuell zumindest im deutschen Bild auch ein Problem ergeben könnte, sind mögliche Dopoelbelegungen der Buchstaben. Ich erinnere mich an Solo an, wo es kaum möglich war sinnvolle Kürzel zu wählen, weil das Orginalkürzel in der Übersetzung nicht vorhanden war und etwas sinnvolles bereits von anderer Stelle belegt war. (Alt +S bei fast allen Spielen geht nur solange kein Speichern via STRG + S genutzt wird. Der Kistenschieber erlaubt aber das Erstellen eigener Level, die man auch speichern kann. 😄)
-
Man muss wieder die ganze Sequenz durchgehen. Also in GeoWrite für Optionen->Werkzeuge Zeigen -> Funktionsleiste: Alt-O - W - F. Das geht auch, wenn das Menü angepinnt ist. Nur das gepinnte Mneü schließen scheint prinzipiell nicht zu gehen.
Rainer
Endlich eine Bestätigung meiner Beobachtung