Menüeintrag reagiert nicht



  • Moin moin

    Ich hab ein Menüproblem - wäre im ersten Moment nicht verwunderlich, allerdings hab ich einen funktinierenden Eintrag und einen ähnlich konfigurierten nicht funktionierenden Eintrag.

    Der 1. Ist unter File -> Open:

    void CProjectDlg::OnFileOpen() 
    {
    	m_oglWindow.loadFile();
    }
    

    Der ruft die loadFile() einwandfei auf.

    Der 2. ist unter View -> New Curve:

    void CProjectDlg::OnNewCurve() 
    {
    	m_oglWindow.createNewCurve();	
    }
    

    Allerdings wird die Funktion createNewCurve() nicht aufgerufen. Beide Menüeinträge sind aktiviert, befinden sich im gleichen Menü...auf den ersten Blick kein Unterschied (abgesehen von der Funktionalität natürlich) Woran kann es liegen? Muss ich irgendwo etwas zusätzlich einstellen?

    Hab eben noch festgestellt, dass in der Funktion OnNewCurve() die automatische Anzeige verfübarer Einträge nicht funktioniert, bei OnOpenFile() hingegen schon.

    Grüße
    Neron


  • Mod

    Nur mal so eine Frage: Menü? Und Deine Klasse ist ein Dialog? Das funktioniert nicht korrekt, wenn Du nicht einiges für das Message Routing selber gemacht hast!

    Zudem werden die Menüpunkte nicht automatisch ausgegraut...

    Existiert denn ein gültiger ON_COMMAND Handler Eintrag in der Messagemap?



  • Also ich hatte eigentlich keine Probleme mit dem Menü bisher. Ich habe meinem Projekt einfach ein Menü hinzugefügt und dem Dialogfenster zugewiesen. In der ProjectDlg.cpp wird auch eine Message Map erstellt, mittels

    BEGIN_MESSAGE_MAP(CProjectDlg, CDialog)
    	//{{AFX_MSG_MAP(CProjectDlg)
    	ON_WM_SYSCOMMAND()
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	ON_WM_SIZE()
    	ON_COMMAND(IDM_FILE_OPEN, OnFileOpen)
    	ON_BN_CLICKED(IDC_SHOWMESH, OnShowmesh)
    	ON_BN_CLICKED(IDC_SHOWSKELETON, OnShowskeleton)
    	ON_BN_CLICKED(IDC_SHOWLATTICE, OnShowlattice)
    	ON_BN_CLICKED(IDC_SHOWLATTICEEDGES, OnShowlatticeedges)
    	ON_COMMAND(IDM_NEW_CURVE, OnNewCurve)
    	ON_COMMAND(IDM_FILE_EXIT, OnFileExit)
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    

    Und dort wird ja auch der ON_COMMAND-Eintrag für New Curve gemacht richtig?



  • Hm, hab das Problem eben selbst gelöst. Ich habe den Eintrag für OnNewCurve() später erstellt als für loadFile(). Daher hab ich eben testweise einfach mal das Menü aus dem Dialog genommen und wieder hinzugefügt und nun funktionierts auch... 😕 😕 😕



  • Ok, wo wir schon dabei sind - ich hab noch ein weiteres Problem jetzt.

    Und zwar möchte ich nach Festlegung einer neuen Kurve über das Menü Edit -> New Curve in einem weiteren Menü einen Eintrag zur Visualisierung der Kurve aktivieren: View -> Curves -> Curve1. Dazu nutze ich folgenden Code:

    HMENU menu = (HMENU)(((CProjectDlg*)hWnd)->GetMenu());
    EnableMenuItem(menu, IDM_VIEW_CURVES_CURVE1, MF_ENABLED);
    

    Der Compiler spuckt mir erstmal keinen Fehler aus, abre im Programm geschieht nix. Eigentlich sollte die Funktion GetMenu() laut MSDN als Eingabe den Handle zum Fenster bekommen, aber VC++ 6 sagt mir, das GetMenu() keine Eingabeparameter hat 😕 Na jedenfalls ist in hWnd das parent gespeichert, in diesem Fall mein Dialogfenster. Ich müßte eigentlich das richtige Menü erhalten, es gibt ja auch keinen Fehler. Woran kann es liegen, dass der Eintrag nicht korrekt aktiviert wird?


  • Administrator

    Wo führst du den Code aus? In CProjectDlg?
    Dann bitte:

    CMenu* pMenu = GetMenu();
    pMenu->EnableMenuItem(IDM_VIEW_CURVES_CURVE1, MF_ENABLE);
    

    Ansonsten wenn wirklich nur das hWnd hast und ausserhalb von CProjectDlg bist, dann vielleicht eher so:

    CWnd* pWnd = CWnd::FromHandle(hWnd);
    CMenu* pMenu = pWnd->GetMenu();
    pMenu->EnableMenuItem(IDM_VIEW_CURVES_CURVE1, MF_ENABLE);
    

    bzw. du schreibst was von Parent. Dann vielleicht so?

    CMenu* pMenu = GetParent()->GetMenu();
    pMenu->EnableMenuItem(IDM_VIEW_CURVES_CURVE1, MF_ENABLE);
    

    Man kann dann auch jeweils prüfen ob die Zeiger ungleich null sind.

    Gibt viele Möglichkeiten, aber das was du machst, würde ich gar nicht empfehlen!

    Grüssli



  • Ich habs nun hinbekommen. Das Problem scheint die Verwendung von HMENU statt CMenu* gewesen zu sein. Nochmal an Dravere...warum würdest du diese Variante nicht empfehlen? Ich habs auch schon mit ON_UPDATE_COMMAND_UI versucht, aber laut MSDN funktioniert das nicht für den CDialog...?


  • Administrator

    Weil du von einem HWND zu einem Zeiger von CWnd und dann den Zeiger von CMenu zu einem HMENU per C-Konvertierung umwandelst, was in meinen Augen sehr unsicher und schlecht ist. Zudem ist die MFC dafür da, dass du eben ohne die Handles auskommst, bzw. so arbeiten kannst, dass du die Objekte direkt ansprichst. Wieso willst du also womöglich ein Zeiger von einem CWnd zu einem HWND konvertieren um dieses HWND später zu deinem CProjectDlg zu konvertieren um damit GetMenu aufzurufen und den erhaltenen Zeiger zu einem HMENU zu konvertieren um dann das HMENU dann per WinAPI zu benutzen? Anstatt einfach direkt mit den Pointer zu arbeiten, bzw. die MFC? Ich meine man kann es natürlich schon unnötig kompliziert, krumm, schräg und fehleranfällig machen, wenn man will, aber das muss doch nicht sein oder?

    Dazu musst du dir vielleicht auch mal im klaren sein, was du benutzen willst. Die MFC oder die WinAPI? Man kann die zwei natürlich auch mischen, aber bitte nicht bei jeder Konvertierung erneut. Schau dir deshalb vielleicht auch mal die Klassen-Members in der MSDN an, normalerweise hat man ja auch eine Offline-Dokumenation, wo man dies sehr schnell nachschauen kann. Da entdeckt man eben in der Suche, dass es ein EnableMenuItem der Windows Management gibt und von der MFC. Die MFC ist schliesslich da, um das Arbeiten mit der WinAPI zu erleichtern. Aber wie du mit der MFC umgehst, da erschwert sie dir nur das Arbeiten 😉

    Grüssli


Anmelden zum Antworten