Kontextmenübefehl wird nicht ausgeführt, wieso?
-
Moin!
Ich habe ein eigenes Listcontrol, dem ich ein Kontextmenü spendiert habe.
In dem Menü ist ein Befehl "Berechnen".
Den will ich nun im View bearbeiten, aber die Funktion dazu wird nie aufgerufen.
im Header:
afx_msg void OnBearbeitenBerechnen(); afx_msg void OnUpdateBearbeitenBerechnen(CCmdUI* pCmdUI);im cpp:
ON_COMMAND(ID_HGLAGER_BERECHNEN, OnBearbeitenBerechnen) ON_UPDATE_COMMAND_UI(ID_HGLAGER_BERECHNEN, OnUpdateBearbeitenBerechnen)void CLagerView::OnBearbeitenBerechnen() { UpdateData(TRUE); // Daten merken m_fBerechnet = TRUE; UpdateData(FALSE); } void CLagerView::OnUpdateBearbeitenBerechnen(CCmdUI* pCmdUI) { pCmdUI->Enable((!m_fBerechnet) && (IstZeileMarkiert())); }Ich habe in beiden Funktionen je einen Breakpoint, aber ich laufe nie auf.

Habt ihr Ideen, wie und nach was ich noch suchen könnte?
-
Hallo,
"laufe nie durch" heißt die Funktion OnBearbeitenBerechnen() wird nicht ausgeführt? Wird die entsprechende Nachricht WM_.... überhaupt abgesetzt? Sonst setze doch einfach mal einen Eintrag in die Menürleiste und schaue da obs geht. Dann kannst du dir erst mal sicher sein, dass die Nachrichtenbehandlung funktioniert.
-
Ich habe jetzt in der PreTranslateMessage folgendes:
if (pMsg->wParam == ID_HGLAGER_BERECHNEN) { if (pMsg->message == WM_COMMAND) { OnBearbeitenBerechnen(); } }Das klappt immerhin schon mal. Allerdings fehlt da ja nun noch das Updaten.
Aber ich denke, wenn es so klappt, dann wird die Nachricht auch gesendet.
-
Bist du dir da sicher? Ich hab bei normalen Menübefehlen noch nie in der PreTranslateMessage rumgeschrieben. Was passiert wenn du einen Eintrag direkt in der Menüleiste anlegst und drauf reagierst, gehts da auch? Was sagt Spy++ dazu? Vielleicht hab ich das mit den Kontextmenüs ja auch falsch verstanden, ich arbeite selten damit. Aber ist deren Verhalten nicht mit dem eines normalen Hauptmenüeintrages zu vergleichen? Über IDs hab ich das glaub ich damals nicht gemacht...
-
AndyDD schrieb:
Was sagt Spy++ dazu?
Tja, da hast du mich eiskalt erwischt.
Ich habe dieses Tool bisher nicht durchschaut und meide es deswegen - bisher ließen sich alle Fehler auch mit Logik finden.Dieser eine Befehl ist nicht im Hauptmenü und soll da auch nicht rein.
Sobald ich das hinbekommen habe, wird es noch mind. einen weiteren in der Art geben.
Das muss doch gehen...
Naja, ich werde mir mal Spy angucken.
-
estartu schrieb:
im Header:
afx_msg void OnBearbeitenBerechnen(); afx_msg void OnUpdateBearbeitenBerechnen(CCmdUI* pCmdUI);im cpp:
ON_COMMAND(ID_BEARBEITEN_BERECHNEN, OnBearbeitenBerechnen) ON_UPDATE_COMMAND_UI(ID_BEARBEITEN_BERECHNEN, OnUpdateBearbeitenBerechnen)estartu schrieb:
if (pMsg->wParam == ID_HGLAGER_BERECHNEN) { if (pMsg->message == WM_COMMAND) { OnBearbeitenBerechnen(); } }Kann es sein, daß du dem Befehl im Kontextmenü einfach nur die falsche ID gegeben hast? Zur Not solltest du mal dein Kontextmenü im Ressourcen-Editor öffnen und die ID anpassen.
-
Ups, Anpassungsfehler.
Ich hatte die IDS hier im Forum abändern wollen und eine vergessen - extrem dämlich, entschuldige.Ich mach oben mal das Original rein.
-
estartu schrieb:
Tja, da hast du mich eiskalt erwischt.
Ich habe dieses Tool bisher nicht durchschaut und meide es deswegen - bisher ließen sich alle Fehler auch mit Logik finden.Tja, so bin ich

Du hast bisher alle Fehler mit Logik gefunden? Du arbeitest doch mit Windows.....
Ja Spy++ ist eine feine Sache, man muss nur wissen nach was man sucht sonst erschlägts einen.
-
Naja, ich habe als Fenster meinen View genommen (dessen Klasse soll das ja behandeln) und als Nachricht WM_COMMAND.
Prompt wurde ich erstmal von EN_UPDATE und EN_CHANGE erschlagen, weil das für jeden Listeneintrag einmal aufgerufen wird bei DeleteAllItems.
Hab ich nun erstmal gesperrt, einmal reicht.
Aber meine gesuchte Nachricht ist nicht dabei, nur EN_UPDATE und EN_CHANGE.

Durch PreTranslateMessage wird sie aber behandelt und auch nicht verschluckt, da ich am Ende immer die Basisklasse noch aufrufe...

-
hatte mal ein ähnliches problem. vielleicht hilft dir ja das hier:
ON_NOTIFY_REFLECT()
-
Red Skall schrieb:
hatte mal ein ähnliches problem. vielleicht hilft dir ja das hier:
ON_NOTIFY_REFLECT()
Danke.

Ich habe das auch schon einige Male in meinem Code, aber nie selbst eingebaut.
Also habe ich in der MSDN gesucht und ein Kapitel gefunden: Defining a Message Handler for a Reflected Message
Da wird das alles auch gut erklärt, leider scheitere ich schon an Schritt 4.To define a message handler for a reflected message with ClassWizard
- in ClassWizard, click the Message Maps tab.
- From the Class name drop-down list, select the name of your control class.
- In the Object IDs box, select the name of your control class.
- In the Messages box, select the message for which you want to define a handler. Your class's reflected messages are marked with an equal sign (=).
A message with a handler already defined is displayed in bold.
Ich sehe da weder etwas mit einem = noch WM_COMMAND, noch die CommandID.

Und das weder bei der Viewklasse noch in der Listcontrolklasse. Naja, in der Listcontrolklasse ist immerhin die CommandID da, aber die Klasse soll das ja nicht behandeln.
-
Okay, ich hatte dann doch noch ne Idee und habe nun folgendes:
void CBasisListCtrl::OnHglagerBerechnen() { AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_HGLAGER_BERECHNEN); }Das in der PreTranslateMessage ist auskommentiert und trotzdem wird der Befehl ausgeführt. Jetzt sogar nach Aufuf und vor Ausführung die OnUpdate...

Allerdings finde ich nicht, wie ich die OnUpdate auslösen kann.void CBasisListCtrl::OnUpdateHglagerBerechnen(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen }
-
mit den wizzards arbeite ich eigentlich nie
von hand ist es meistens eh schneller als vom code-generator von MS.das einbinden ist eigentlich kein problem:
// *.h afx_msg void OnLvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult);BEGIN_MESSAGE_MAP(CDeinListCtrl, CListCtrl) ON_NOTIFY_REFLECT(LVN_BEGINLABELEDIT, OnLvnBeginlabeledit) END_MESSAGE_MAP() void CDeinListCtrl::OnLvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult) { NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR); // ... *pResult = 0; }mehr habe ich zumindest nicht gemacht

EDIT:
Sorry, doppelpost
-
Okay, das habe ich mittlerweile hinbekommen (mit Wizard, ich habe mich sehr dran gewöhnt) - hatte da nen Brett vorm Kopf.
Hast du noch eine Idee zu meiner nachgeschobenen Frage?
-
ne sorry. ich muss auch zugeben das ich nichtmal weis wozu OnUpdate...() gut ist und wie es aufgerufen wird

was macht denn die funktion und was willst du damit erreichen ?
-
Das ist die Funktion, in der ich einen Menüpunkt ausgrauen kann, falls er nicht aufgerufen werden soll.
Im konkreten Fall sieht das so aus:void CLagerView::OnUpdateBearbeitenBerechnen(CCmdUI* pCmdUI) { pCmdUI->Enable((!m_fBerechnet) && (IstZeileMarkiert())); }Der Menüpunkt darf nur enabled sein, wenn eine Zeile markiert ist und diese noch nicht berechnet wurde.
-
du könntest diesen schritt ja umgehen indem du direkt vor 'TrackPopupMenu()' die entsprechenden menüeinträge deaktivierst

-
Hmm, das kann ich Montag mal versuchen. Danke.

-
bei mir funktioniert es so wunderbar, dann sicherlich auch bei dir

finde das so aber auch sauberer programmiert
*nicht klugscheissen wollen* 
-
Red Skall schrieb:
finde das so aber auch sauberer programmiert
*nicht klugscheissen wollen* 
Sauberer als was?
Als mit PreTranslateMessage? Auf jeden Fall, das war ja auch nur eine vorübergehende Lösung, weil ich so gleich getestet hatte, ob die Nachricht überhaupt funktioniert.
-
nene, sauber als OnUpdate...() meine ich. denn du rufst das menü auf und deaktivierst in dieser funktion menüeinträge.
besser ist finde ich das menu zu erzeugen, dann alles deaktivieren was man deaktiviert haben möchte und es dann anzuzeigen.
ist geschmackssache würde ich sagen
