[gelöst] Editcontrol subclassed
-
Ich setze für Editcontrols subclasses ein, um die Eingabe auf Zulässigkeit (z.B. nur Ziffern 0 bis 9) zu prüfen. Im erkannten Fehlerfall erfolgt ein Beep und in der programmeigenen Statuszeile der Text "Fehler!" Das funktioniert einwandfrei, doch der Anwender muss dann das falsche Zeichen selbst löschen. Ich suche nach einer Möglichkeit, das letzte Eingabezeichen ohne Beep und Fehlermeldung einfach ignorieren zu können. Da der Fehler in der CALLBACK-Funktion der subclasses erkannt wird, will ich auch dort reagieren und weiss nicht wie.
Edit: Bellis Vorschlag ist O.K. Hatte allein WM_KEYUP, nicht auch WM_CHAR berücksichtigt.
-
Bevor Du die Default-Window-Prozedur aufrufst, setz wParam auf 0, wenn ein falsches Zeichen eingegeben wurde.
-
@Belli: wParam = 0 bleibt ohne Wirkung, es ist noch mehr erforderlich. Setze ich auch noch msg = EM_UNDO oder WM_UNDO verschwindet der gesamte Eingabetext. Es soll aber nur das zuletzt eingegebene falsche Zeichen weg. Irgendwie sollte das schon über die Parameter in return CallWindowProc aus der Subclass-Funktion oder mit SendMessage an das Editcontrol gehen. Ist eigentlich keine grosse Sache und für den Anwender vielleicht auch nicht so gut, weil er seine Fehler so nicht bemerkt. Ein versehentliches CapsLock und der Anwender verzweifelt. Ich denke, ich belasse es bei einem Beep und einem Hinweis in der Statuszeile des Programmes. Dieser Service sollte für den Anwender reichen.
-
Waum nicht einfach:
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CHAR: if((wParam<'0' || wParam>'9') && wParam != '\b') { return 0; } } WNDPROC editproc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(hwnd, GWL_USERDATA)); return editproc?CallWindowProc(editproc,hwnd,msg, wParam, lParam):0; }Falls also die Eingabe fehlerhaft war, wird die Standardproc nicht aufgerufen. Zeichen wie '.' oder ',' müßten ggf. hinzugefügt werden.
-
Achja, ein break habe ich vergessen. Hinzufügen sollte ich vielleicht auch, dass dies natürlich nur funktioniert, wenn vorher so etwas durchlaufen wird:
HWND edit = GetDlgItem(hwnd, ID_DES_CONTROLS); SetWindowLongPtr(edit, GWL_USERDATA, GetWindowLongPtr(edit, GWL_WNDPROC)); SetWindowLongPtr(edit, GWL_WNDPROC, reinterpret_cast<LONG_PTR>(EditProc));
-
Gut, man kann das schon machen. Es gibt aber noch den Gesichtspunkt der Software-Ergonomie und da sollte man so etwas vielleicht doch besser bleiben lassen?
-
berniebutt schrieb:
@Belli: wParam = 0 bleibt ohne Wirkung, es ist noch mehr erforderlich.
Versteh ich nicht ... ich habe ein Programm, da funktioniert
WNDPROC wpOrigEditProc; LRESULT APIENTRY EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CHAR: if((wParam < '0' || wParam > '9') && wParam != '.') wParam = 0; break; //Hier folgen bei mir noch weitere Messages ... } return CallWindowProc(wpOrigEditProc, hwnd, uMsg, wParam, lParam); }einwandfrei. Der 'Beep' wird hierbei automatisch mitgeliefert ...
Edit: Beachte, daß die Default - Windowprozedur auf jeden Fall aufgerufen wird.
-
berniebutt schrieb:
Ich suche nach einer Möglichkeit, das letzte Eingabezeichen ohne Beep und Fehlermeldung einfach ignorieren zu können.
Ich verstehe es auch nicht. Die Funktionalität die du haben wolltest, habe ich doch gepostet
