Tastatureingaben abfangen

Michbeck1983

Mitglied
Hallo,

ich habe folgendes Problem:

Ich habe einen Dialog, auf dem ein Tab-Control sitzt. Dieses hat zwei Kind-Dialoge, die in den einzelnen Tabs angezeigt wird.
Soweit alles in Ordnung, das Problem ist nur, dass diese Kind-Dialoge geschlossen werden, wenn man "Enter" oder "Escape" eingibt.

Ich versuche nun, mit der Methode "PreTranslateMessage" diese abzufangen. Hier der Code:

Code:
BOOL CDVDDatabaseDlg::PreTranslateMessage(MSG* pMsg)
 {
 	if(pMsg->message == WM_KEYDOWN)
 	{
 		if(pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)
 			pMsg->wParam = NULL;
 	}
 
 	return CDialog::PreTranslateMessage(pMsg);
 }

Das Problem ist, dass mein Programm schon bei der ersten If-Abfrage abbricht; ich habe keine Ahnung warum, bzw. verstehe es nicht.

Weiß jemand Abhilfe?
 
Nach der ersten IF - Anweisung ? Dies sieht eigentlich riechtig aus.
Du musst aber, um Enter und Escape nicht zu bearbeiten ein "return TRUE;" ausführen anstatt den wParam auf NULL zu setzten.

Evtl. solltest du auch prüfen, welches CWnd die Nachricht geschickt hat.
Das kannst du mit der Methode "GetSafeHwnd()" eines entsprechenden CWnd-Objekts.

Den Fensterhandle kannst du dann mit dem aus "pMsg->hwnd" vergleichen, um z.B. nur von bestimmten Steuerelementen / Fenstern die Tasten zu blockieren.

M.f.G. Erik
 
Das Problem hatte ich auch schon mal, ist aber ganz einfach zu lösen. Du mußt nur in den zugehörigen Dialogklassen OnOK() und OnCancel() überschreiben, ohne die Funktionen der Basisklasse aufzurufen. Dann bleiben Deine Dialoge offen. Das mit PreTranslateMessage kannst Du dann weglassen.
Grüße, jokey2
 
Also das mit dem GetSafeHwnd() werde ich jetzt gleich mal ausprobieren.

Was das OnOK und OnCancel betrifft - diese Methoden sind in den Kindklassen gar nicht vorhanden, weil ich darauf gar keine CommandButtons habe? Wie kann bzw. wie soll ich die dann überschreiben
 
Dein Dialog ist doch von CDialog abgeleitet. Dort gibt es die Nachrichten-Behandlungsmethoden OnOK() und OnCancel(), die automatisch vom Programmgerüst aufgerufen werden und das Fenster schließen. Standardmäßig wird OnOK() auch beim Drücken von ENTER aufgerufen, so wie OnCancel beim Drücken von ESC aufgerufen wird. Wenn Du in Deiner Klassendeklaration die Funktionsdeklarationen
Code:
void OnOK(){};
void OnCancel(){};
(inline-Deklaration) anlegst, werden diese aufgerufen, statt der Funktionen der Basisklasse. Die deklarationen mußt Du allerdings per Hand anlegen.
Grüße, jokey2
 
Hm, also wenn ich dich jetzt nicht falsch verstanden habe, dann hatte das irgendwie keinen Effekt; die Dialoge haben sich trotzdem geschlossen...

Habe in den beiden Klassen für die Tab-Dialoge wie du geschrieben hast OnOK und OnCancel in den Header geschrieben (Inline-Deklaration). Trotzdem schließen sich die Dialoge, wenn ich in den Debugger schaue, werden die Funktionen gar nicht aufgerufen... es ist zum verzweifeln :-(
 
Das mit OnOK() und OnCancel() dürfte nicht gehen -
in einem modalen Dialog schon aber nicht wenn du nur 2 Objekte vom typ CDialog hast. (ich nehm das jetzt einfach mal an da mir keine andere Mögichkeit bekannt 2Kind-Dialog in ein TabCtrl einzufügen)

Und für die kann man nicht diese Behandlungsroutinen einfügen da sie nicht mit DoModal() "gestartet wurden". Das sind quasie die leblosen Hüllen des Ressourcen Editor. ^_______^
Was es auch recht schwierig mach auf einen Button zu reagieren der in diesen Dialogen ist.

Falls ich mich irre bitte ich umgehend um Korrektur !

~~+#+~~

Ich hab da gerade was gefunden, da ich das auch brauche - falls du VisualStudio .NET verwendest, kannst du das im Resourcen editor was einstellen :

(ich hab die englsiche Version also ist meine Beschreibung jetzt auch auf Englisch)
- gehst in die Resourcenansicht zu deiner Proppage Dialog
- öffnest das Toolfenster "Properties"
- und stellst da unter "Misc" -> "Control" = TRUE ein

dann geht bei mir der ganze Dialog zu und das wiederung kann man dann mit OnOK und OnCancel behandeln.

M.f.G. Erik
 
Zuletzt bearbeitet:
Mit deiner Annahme hast du Recht.

Habe es jetzt so gemacht, wie du geschrieben hast (mit der deutschen Version von .NET). Jetzt schließt sich der ganze Dialog, wie du geschrieben hast.

Jetzt muss ich halt leider so blöd fragen: Wie gehe ich weiter vor Wenn ich in den Klassen-Header eine Inline-Deklaration von OnOK() mache, die nichts enthält, schließt sich der Dialog trotzdem...
 
Ich bastle gerade rum und versuche irgendwie die Nachrichten abzufangen aber das ist ganz komisch. ^__^

Auf jeden fall kanst due jetzt die virtuellen Funktionen OnOK() (bei Enter) und OnCancel() (bei Escape) benutzen um was zu speichern oder eine Abfrage anzuzeigen ob der Dialog wirklich geschlossen werden soll.

Und so gehts: Du gehst in die Klassenansicht/Class View und klickst mit rechts auf die Klasse des Dialogs, welcher das TabCtrl enthält. Wählst Eigenschaften/Properties und klickst dann in dem Toolfenster auf die kleine, grüne Kiste (das sysmbol für "Overrides")
Da siehst du ugendwo OnCancel() und OnOK() und fügst di hinzu.

In diesen Funktionen kannst du dann dein zeug machen - das eigentliche schliessen wird durch CDialog::OnOK() oder CDialog::OnCancel() bewirk - wird das nicht aufgerufen geht der Dialog nich zu allerding dann auch nchtmehr durch den OK oder ABBRECHEN Button.
 
Halt : ich hab ne praktische Lösung gefunden:

Bei OnOK(); und OnCancel() kommentierst du das CDialog::OnOK() und CDialog::OnCancel() aus.

den "Ok" Button gibst du eine Andere ID als IDOK und fügst ein OnButton hinzu an deren ende du dann CDiallog::OnOK() aufrufst. (so auch mit "Abbrechen")

Das hat zur folge, das die Standard behandlung von OnOK() und Cancel() dein Programm nicht schliesst was du aber "manuell" mit den Button kannst.

Verdammt wieso ist mir das nicht schon früher eingefallen ^___^

M.f.G. Erik
 

Neue Beiträge

Zurück