Technician Geschrieben 8. Oktober 2004 Geschrieben 8. Oktober 2004 Hallo, das Problem bezieht sich auf VC++6.0 mit MFC. Mein Programm enthält ein RichEdit-Feld, in dem der Benutzer Eingaben tätigen kann, jedoch nur mit folgenden Einschränkungen: Löschen und die Eingabe von Zeichen ist nur in der jeweils letzten Zeile möglich; in den vorhergehenden Zeilen darf der Benutzer lediglich navigieren und markieren aber nichts ändern. Meine Idee, dies zu realisieren, ist nun folgende: Beim Drücken einer Taste soll die aktuelle Position des Text-Cursors im RichEdit-Feld ermittelt werden (daraus kann ich berechnen, in welcher Zeile sich der Cursor befindet), und je nach Zeile die betreffenden Tasten (d.h., alle außer den Cursor-Tasten) sperren. Aber ich habe dabei zwei Probleme: 1.) mit welcher Methode/ welchem Ereignis kann ich die aktuell gedrückte Taste abfragen? OnChangeRichedit wird ja nur ausgeführt, wenn sich etwas im Textfeld ändert (Änderung ist dann schon durchgeführt); ich möchte aber beim Drücken einer Taste diese sofort sperren und die Eingabe gar nicht erst zulassen. Pseudocode: OnTasteGedrückt ( Taste) { cursorPos = ErmittleCursorPosition; wenn(cursorPos == xyz) //wenn cursorPos der letzten Zeile entspricht { wenn(Taste == unerlaubt) { //tastendruck wirkt sich nicht aus } ansonsten { //tastendruck wirkt sich wie gewöhnlich aus } } } 2.) wie ermittle ich die aktuelle Cursor-Position in einem RichEdit-Feld? Ich hoffe, ihr könnt mir weiterhelfen Viele Grüße, Technician Zitieren
Guybrush Threepwood Geschrieben 8. Oktober 2004 Geschrieben 8. Oktober 2004 Versuchs mal mit OnChar oder OnKeyDown. Wie du die aktuelle Position in einem RichEdit bekommst weiß ich nicht. Hast du schonmal hier geguckt? Zitieren
Technician Geschrieben 8. Oktober 2004 Autor Geschrieben 8. Oktober 2004 Versuchs mal mit OnChar oder OnKeyDown. hmmm, aber auf welches Ereignis soll OnChar oder OnKeyDown reagieren?! Ich finde in der Ereignisliste nichts Passendes Zitieren
Technician Geschrieben 8. Oktober 2004 Autor Geschrieben 8. Oktober 2004 Wie du die aktuelle Position in einem RichEdit bekommst weiß ich nicht. Hast du schonmal hier geguckt? Dort bin ich leider auch nicht schlauer geworden. Zitieren
Guybrush Threepwood Geschrieben 8. Oktober 2004 Geschrieben 8. Oktober 2004 hmmm, aber auf welches Ereignis soll OnChar oder OnKeyDown reagieren?! Ich finde in der Ereignisliste nichts Passendes Also ich habe gerade mal mit dem Klassenassistenten eine MFC Anwendung samt RichEdit gemacht. Danach hab ich im Klassen-Assistent WM_CHAR für die View Klasse abgefangen. Er hat dann eine OnChar Methode für die Klasse erstellt in die er immer reinspringt wenn im RichEdit eine Taste gedrückt wird. Sorry wenns etwas ungenau war, aber ich mach normalerweise nix mit der MFC Dort bin ich leider auch nicht schlauer geworden. Es gibt eine GetSel Funktion für die RichEdit Klasse hast du mal geguckt was sie dir zurück liefert. Vielleicht klappt das ja auch wenn nichts ausgewält ist und die beiden Werte sind dann gleich => also die aktuelle Cursor-Position im Text. Zitieren
Technician Geschrieben 9. Oktober 2004 Autor Geschrieben 9. Oktober 2004 Es gibt eine GetSel Funktion für die RichEdit Klasse hast du mal geguckt was sie dir zurück liefert. Vielleicht klappt das ja auch wenn nichts ausgewält ist und die beiden Werte sind dann gleich => also die aktuelle Cursor-Position im Text. GetSel gibt den selektierten Text bzw. (in der überladenen Methode) die Position (von - bis) der Selektion zurück. Wenn nichts ausgewählt wurde, kriege ich damit die aktuelle Cursor-Position. Das funktioniert also Also ich habe gerade mal mit dem Klassenassistenten eine MFC Anwendung samt RichEdit gemacht. Danach hab ich im Klassen-Assistent WM_CHAR für die View Klasse abgefangen. Er hat dann eine OnChar Methode für die Klasse erstellt in die er immer reinspringt wenn im RichEdit eine Taste gedrückt wird. Hast du ein FormView-Projekt oder ein CRichEditView-Projekt erstellt? Was ich brauche (da das Fenster nicht nur ein RichEdit-Feld, sondern diverse Steuerelemente enthält) ist ein FormView-Projekt. Wenn ich ein CRichEditView-Projekt mache, dann funktioniert die von dir beschriebene Vorgehensweise. Versuche ich hingegen das selbe mit einem FormView-Projekt, so passiert schlichtweg _nichts_, wenn man eine Taste drückt (schreibt das Zeichen ins RichEdit, aber springt nicht in die Methode). Desweiteren: wenn das als Behandlung der WM_CHAR-Nachricht irgendwie zum Laufen zu bekommen wäre, so würde das Programm immer in die Methode springen, wenn irgendwo eine Taste gedrückt wird, und nicht nur im RichEdit. Deshalb bräuchte ich eigentlich eine RichEdit-eigene Nachricht. Viele Grüße, Technician Zitieren
Guybrush Threepwood Geschrieben 9. Oktober 2004 Geschrieben 9. Oktober 2004 GetSel gibt den selektierten Text bzw. (in der überladenen Methode) die Position (von - bis) der Selektion zurück. Wenn nichts ausgewählt wurde, kriege ich damit die aktuelle Cursor-Position. Das funktioniert also Ich seh grad das du mit LineFromChar direkt ide aktuelle Zeile bekommen kannst. Hast du ein FormView-Projekt oder ein CRichEditView-Projekt erstellt? Was ich brauche (da das Fenster nicht nur ein RichEdit-Feld, sondern diverse Steuerelemente enthält) ist ein FormView-Projekt. Wenn ich ein CRichEditView-Projekt mache, dann funktioniert die von dir beschriebene Vorgehensweise. Versuche ich hingegen das selbe mit einem FormView-Projekt, so passiert schlichtweg _nichts_, wenn man eine Taste drückt (schreibt das Zeichen ins RichEdit, aber springt nicht in die Methode). Hatte ein CRichEditView-Projekt erstellt, in dem anderem gehts bei mir komischer Weise auch nicht. Desweiteren: wenn das als Behandlung der WM_CHAR-Nachricht irgendwie zum Laufen zu bekommen wäre, so würde das Programm immer in die Methode springen, wenn irgendwo eine Taste gedrückt wird, und nicht nur im RichEdit. Deshalb bräuchte ich eigentlich eine RichEdit-eigene Nachricht. Naja du könntest in der Metohde überprüfen ob das RichEdit im Moment den Focus hat. Zitieren
Technician Geschrieben 9. Oktober 2004 Autor Geschrieben 9. Oktober 2004 Hatte ein CRichEditView-Projekt erstellt, in dem anderem gehts bei mir komischer Weise auch nicht. Mit einem CRichEditView-Projekt kann ich leider nichts anfangen; ich muss ein CFormView-Projekt verwenden. Naja du könntest in der Metohde überprüfen ob das RichEdit im Moment den Focus hat. Das ginge natürlich, wennauch eine CRichEdit-eigene Methode eleganter wäre. Aber da es anscheinend eine solche Methode nicht gibt, werde ich das so machen müssen. Jetzt muss "nur" noch das Abfangen von WM_CHAR irgendwie funktionieren... Zitieren
Guybrush Threepwood Geschrieben 9. Oktober 2004 Geschrieben 9. Oktober 2004 Jetzt muss "nur" noch das Abfangen von WM_CHAR irgendwie funktionieren... Ich weiß jetzt wo das Problem ist. Das RichEdit sendet standardmäßig keine NOTIFY Nachrichtan an seine Parents. Das kannst du im Konstruktor mit m_yourRichEdit.SetEventMask(ENM_KEYEVENTS); [/PHP] ändern. Zitieren
Technician Geschrieben 10. Oktober 2004 Autor Geschrieben 10. Oktober 2004 Ich weiß jetzt wo das Problem ist. Das RichEdit sendet standardmäßig keine NOTIFY Nachrichtan an seine Parents. Das kannst du im Konstruktor mit m_yourRichEdit.SetEventMask(ENM_KEYEVENTS); [/PHP] ändern. Hm, das hatte ich schon gemacht, hilft aber nicht. Ich habe ENM_CHANGE gesetzt, damit reagiert das RichEdit aufs Change-Ereignis. Das klappt. Ich habe jetzt auch ENM_KEYEVENTS gesetzt, aber WM_CHAR, WM_KEYDOWN, WM_KEYUP sind dem Programm immer noch schnuppe... Zitieren
Guybrush Threepwood Geschrieben 10. Oktober 2004 Geschrieben 10. Oktober 2004 Hm, das hatte ich schon gemacht, hilft aber nicht. Ich habe ENM_CHANGE gesetzt, damit reagiert das RichEdit aufs Change-Ereignis. Das klappt. Also kannst du das da drin machen oder brauchst du immer noch WM_CHAR? Zitieren
Technician Geschrieben 10. Oktober 2004 Autor Geschrieben 10. Oktober 2004 Also kannst du das da drin machen oder brauchst du immer noch WM_CHAR? Das hilft mir nicht viel; ich werde WM_CHAR brauchen. ENM_CHANGE reagiert auf Änderungen im RichEdit-Feld (nach dem Motto "Achtung, RichEdit-Inhalt hat sich geändert"); es sagt mir nicht, welche Taste gedrückt wurde. Genau das müsste ich aber wissen: welche Taste gedrückt wurde. Zur Erinnerung, ich will ja folgendes: OnTasteGedrückt ( Taste) { cursorPos = ErmittleCursorPosition; wenn(cursorPos == xyz) //wenn cursorPos der letzten Zeile entspricht { wenn(Taste == unerlaubt) { //tastendruck wirkt sich nicht aus } ansonsten { //tastendruck wirkt sich wie gewöhnlich aus } } } ähmmmmm, Moment mal, mir fällt was ein: Ich könnte das ja so machen: Inhalt des RichEdits in Variable oldContent wenn Aufruf von ENM_CHANGE: Cursor-Pos ermitteln wenn Cursor-Pos in letzter Zeile so lassen ansonsten aus oldContent zurückschreiben Das probier ich heute noch aus und melde mich dann nochmal, ob mir das weiterhilft! Viele Grüße, Technician Zitieren
Technician Geschrieben 10. Oktober 2004 Autor Geschrieben 10. Oktober 2004 genau, jetzt mach ich's so, und das tut was es soll: ähmmmmm, Moment mal, mir fällt was ein: Ich könnte das ja so machen: Inhalt des RichEdits in Variable oldContent wenn Aufruf von ENM_CHANGE: Cursor-Pos ermitteln wenn Cursor-Pos in letzter Zeile so lassen ansonsten aus oldContent zurückschreiben Zitieren
Guybrush Threepwood Geschrieben 10. Oktober 2004 Geschrieben 10. Oktober 2004 Trotzdem finde ich es komisch das das andere nicht funktioniert. Das wäre auch eine schönere/perfomantere Lösung gewesen... Zitieren
Shark21 Geschrieben 13. Juli 2005 Geschrieben 13. Juli 2005 Also ich hab so was ähnliches gemacht (Abfangen einer F11 Taste). Habe auch erst stundenlang mich mit WM_CHAR, _KEYUP, _KEYDOWN rumgeärgert. Versuch es mal mit der netten Funktion "PreTranslateMessage(MSG *pMsg)". pMsg->wParam ist dann die Taste (z.B. VK_F11 in meinem Fall). Genaueres steht ja in der MSDN. Klappte alles auf Anhieb wunderbar Hoffe damit geholfen zu haben, obwohl´s ziemlich spät ist Denn ich suche nach einer Möglichkeit, die Position des Cursors in einem String herauszufinden, das hier ist leider etwas anderes. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.