Menü wechseln



  • LowFly schrieb:

    hmm geh ich richtig in der annahme das du vc8 bzw 2005 version hast?
    dann versuch mal eine neue Documentenclasse zu erstellen diese von CDocument abzuleiten so hat es zumindest linus gemacht der hatte das gleiche problem mit der abstracten klasse.

    Jep, du gehst richtig in der Annahme. VS 2005

    LowFly schrieb:

    evtl könntest du auch mal versuchen bevor du die CREATESTRUCT an CScrollView::PreCreateWindow(cs) sie von dem actuellen fenster zu holen. wenn das ncit hilft halt den flag setzen.

    Wie kann ich die vom aktuellen Fenster holen? Das Flag weiß ich zwar gerade auch nicht, aber das lässt sich ja in der MSDN finden 😉

    Hab gerade keine Zeit das ganze auszuprobieren, werde es aber später mal versuchen!

    danke, mfg



  • ja muste auch erst nachkucken in der MSDN
    an den style kommst du evtl mit .

    DWORD dwStyle = (DWORD)GetWindowLong(m_hWnd, GWL_STYLE);
    dwStyle  &= ~WS_MAXIMIZEBOX;//Deaktiviert die Maximieren button
    dwStyle  &= ~WS_MINIMIZEBOX;//Deaktiviert die Minimieren button
    cs.style = dwStyle;
    CScrollView::PreCreateWindow(cs);
    

    bzw könntest du ihn auch direct von der Function holen

    BOOL C...::PreCreateWindow(CREATESTRUCT& cs)
    {
    	cs.style |= WS_SYSMENU;//Systemenu hinzufügen
    	cs.style &= ~WS_MAXIMIZEBOX;//Deaktiviert die Maximieren button
    	cs.style &= ~WS_MINIMIZEBOX;//Deaktiviert die Minimieren button
    	return CScrollView::PreCreateWindow(cs);
    }
    

    und die styles findest du unter WS_ 😉



  • Soda mir reichts jetzt!

    Irgendwie funktioniert hier überhaupt nichts mehr...

    Gibt es nicht irgend einen einfacheren Weg das ganze zu lösen?

    Dabei könnte ich mir vorstellen einfach auf die 2 unterschiedlichen Menüs zu verzichten und immer das selbe zu zeigen (also das gleiche Menü beim start des Programms, bzw. wenn kein Dokument mehr geöffnet ist und wenn Dokument(e) geöffnet sind).
    Dabei sollten halt lediglich jene Funktionen, die ohne geöffnetes Dokument keinen Sinn machen deaktiviert sein (ist ja denke ich Standardmäßig so, wenn keine View geöffnet ist, welche die Messages empfängt).

    Dann müsste ich ja lediglich beim ändern der Sprache das Menü austauschen und fertig??? Was müsste ich im Programm jetzt umstellen, damit nur noch 1 Menü verwendet wird (Stichwort CMultiDocTemplate im App)?

    Danke für die große Ausdauer mit mir. Hoffentlich könnt ihr mir auch weiterhin helfen!

    mfg



  • Was müsste ich im Programm jetzt umstellen, damit nur noch 1 Menü verwendet wird (Stichwort CMultiDocTemplate im App)?

    hmm 😕 versteh nicht ganz was du meinst

    m_pDocTemplate = new CMultiDocTemplate(
            [b]IDR_MENUDASGELADENWIRD[/b],//<----das ist das Menu was immer geladen wird
            RUNTIME_CLASS(xxxDoc),
            RUNTIME_CLASS(CChildFrame), 
            RUNTIME_CLASS(xxxView));
    


  • Ohne das jetzt ausprobiert zu haben steh ich dann aber wieder vor dem Problem, dass bei jedem öffnen eines neuen Dokuments wieder das Standard-Menü (also in dem Fall Englisch) geladen wird und nicht jenes, dass aktuelle eingestellt ist (also zB. Deutsch).

    Naja, werd mal wieder ein wenig herumspielen und trotzdem nicht weiterkommen 😢 (sorry, aber schön langsam nervt mich das ganze einfach)

    mfg



  • also was mir da noch einfallen würde bzw. schon länger ist,
    erstell dir doch in der App einfach ein zweites MultiDocTemplate

    m_pDocTempEng = new CMultiDocTemplate(
            IDR_MENU_ENGLISH,
            RUNTIME_CLASS(xxxDoc),
            RUNTIME_CLASS(CChildFrame), 
            RUNTIME_CLASS(xxxView));
    
    m_pDocTempGer = new CMultiDocTemplate(
            IDR_MENU_GERMAN,
            RUNTIME_CLASS(xxxDoc),
            RUNTIME_CLASS(CChildFrame), 
            RUNTIME_CLASS(xxxView));
    

    je nachdem welche sprache eingestellt wurde übergibst du zu Beginn an

    AddDocTemplate(....);
    

    das jeweilige MultiDoc für die Sprache des Menus.

    und evtl würde es gehn das du wärend der laufzeit mit

    ((CChangeViewsApp*)AfxGetApp())->AddDocTemplate(NULL);
    ((CChangeViewsApp*)AfxGetApp())->AddDocTemplate(m_pDocTemp...);
    

    das MultiDoc änderst aber das hab ich jetzt nicht probiert wäre nur sone idee
    😉



  • LowFly schrieb:

    m_pDocTemplate = new CMultiDocTemplate(
            [b]IDR_MENUDASGELADENWIRD[/b],//<----das ist das Menu was immer geladen wird
            RUNTIME_CLASS(xxxDoc),
            RUNTIME_CLASS(CChildFrame), 
            RUNTIME_CLASS(xxxView));
    

    Hab das jetzt mal versucht, aber irgendwie ändert das nichts:

    Der Aufruf sieht jetzt folgendermaßen aus:

    m_pDocTemplate = new CMultiDocTemplate(IDR_xxxTYPE,
    		RUNTIME_CLASS(CxxxDoc),
    		RUNTIME_CLASS(CChildFrame), // custom MDI child frame
    		RUNTIME_CLASS(CxxxView));
    
    	if (!m_pDocTemplate)
    		return FALSE;
    
    	AddDocTemplate(m_pDocTemplate);
    

    Angezeigt wird beim Programmstart trotzdem nicht das Menü IDR_xxxType, sonder IDR_MAINFRAME, also wird das Menü wohl wo anders geladen. Die Frage ist nur, wo? (Das Problem hab ich jetzt umgangen, indem ich in der InitInstance ganz am Schluss einfach mein AppChangeLanguage aufrufe, welches unter anderem auch die unten geschilderte Methode SetMenu vom MeinFrame ausführt. So wird anhand eines Registry-Eintrages zumindest beim Start das zuvor verwendete Sprach-Menü angezeigt ;))

    LowFly schrieb:

    also was mir da noch einfallen würde bzw. schon länger ist,
    erstell dir doch in der App einfach ein zweites MultiDocTemplate

    m_pDocTempEng = new CMultiDocTemplate(
            IDR_MENU_ENGLISH,
            RUNTIME_CLASS(xxxDoc),
            RUNTIME_CLASS(CChildFrame), 
            RUNTIME_CLASS(xxxView));
    
    m_pDocTempGer = new CMultiDocTemplate(
            IDR_MENU_GERMAN,
            RUNTIME_CLASS(xxxDoc),
            RUNTIME_CLASS(CChildFrame), 
            RUNTIME_CLASS(xxxView));
    

    Das kann ich nicht machen, da die Sprach-Ressourcen nicht fix im Programm eingebetet sind, sondern als Sprach-Dll's zur Verfügung stehen, welche dynamisch geladen werden, dh. das Programm weiß im Prinzip gar nicht, welche Sprachen vorhanden sind (das ganze soll einfach und vor allem unbegrenzt erweiterbar sein).

    Die Umschaltung der Sprache erfolgt über folgende Methode, die im FrmMain definiert ist:

    void CMainFrame::SetMenu()
    	{
    	CMenu menu;
    	HMENU hMenu;
    
    	hMenu = theApp.AppGetLangMenu(IDR_xxxTYPE);
    	if (hMenu == NULL)
    		return;
    
    	menu.Attach(hMenu);
    
    	CWnd::SetMenu(NULL);
    	CWnd::SetMenu(&menu);
    	::DrawMenuBar(m_hWnd);
    	}
    

    Beim starten des Programms wird über eben diesen Befehl das Menü der zuletzt verwendeten Sprache geladen. Nun stehe ich wieder vor dem Problem, dass beim öffnen eines neuen Dokuments wieder das Standard-Menü und nicht das Sprach-Spezifische geladen wird.

    Und noch ein (bereits bekanntes) Problem: Wenn ein Dokument geöffnet wurde und ich dann erst die Sprache umschalte (mit oben geposteter Methode) verschwinden die System-Button (maximieren, minimieren, schließen) des Dokuments...

    Ich weiß, dass sich das alles schon ziemlich im Kreis dreht und das bestimmt für euch/dich schon ziemlich nervig und anstrengend sein muss, aber ich hoffe trotzdem, dass ich gemeinsam mit euch eine Lösung finden kann!

    danke, mfg



  • hmm also als allerletzte möglichkeit würde mir jetzt noch einfallen menupunkte gezielt zu zerstöhren & wieder neu zu beschriften. kuck dir mal die klasse CMenu genauer an. du kannst jeden einzelnen menupunkt in einem bereits bestehenden Menu zerstöhren und an seiner stellen einen anderen Menupunkt einfügen.

    nur ist halt ne crasse arbeit das zu bewerkstelligen.



  • Die Möglichkeit ist mir auch schon in den Sinn gekommen, allerdings hab ich sie gleich wieder verworfen (wegen dem doch relativ großen Aufwand). Vor allem ist das Programm noch nicht ganz fertig, dass heißt bei jeder Änderung des Menüs entsteht hier wieder ein "unnötig" großer Aufwand...

    Naja, sollte ich anders wirklich nicht weiterkommen wird es wohl keine andere Möglichkeit als diese geben.

    danke, mfg



  • Muss mich hier wieder melden (war ja auch nicht anders zu erwarten ;))

    Hab zwar die Sprachumschaltung mal hinten angestellt aber bin gerade wieder auf ein Problem gekommen, welches ich dann doch relativ schnell lösen sollte:

    Ich hab mich ja jetzt dazu entschieden immer das selbe Menü anzuzeigen (also kein abgespecktes Menü, wenn kein Dokument geöffnet ist).

    Das Problem dabei hab ich ja vorher schon beschrieben und ich es umgangen habe:

    suamikim schrieb:

    LowFly schrieb:

    m_pDocTemplate = new CMultiDocTemplate(
            [b]IDR_MENUDASGELADENWIRD[/b],//<----das ist das Menu was immer geladen wird
            RUNTIME_CLASS(xxxDoc),
            RUNTIME_CLASS(CChildFrame), 
            RUNTIME_CLASS(xxxView));
    

    Hab das jetzt mal versucht, aber irgendwie ändert das nichts:

    Der Aufruf sieht jetzt folgendermaßen aus:

    m_pDocTemplate = new CMultiDocTemplate(IDR_xxxTYPE,
    		RUNTIME_CLASS(CxxxDoc),
    		RUNTIME_CLASS(CChildFrame), // custom MDI child frame
    		RUNTIME_CLASS(CxxxView));
    
    	if (!m_pDocTemplate)
    		return FALSE;
    
    	AddDocTemplate(m_pDocTemplate);
    

    Angezeigt wird beim Programmstart trotzdem nicht das Menü IDR_xxxType, sonder IDR_MAINFRAME, also wird das Menü wohl wo anders geladen. Die Frage ist nur, wo? (Das Problem hab ich jetzt umgangen, indem ich in der InitInstance ganz am Schluss einfach mein AppChangeLanguage aufrufe, welches unter anderem auch die unten geschilderte Methode SetMenu vom MeinFrame ausführt. So wird anhand eines Registry-Eintrages zumindest beim Start das zuvor verwendete Sprach-Menü angezeigt ;))

    Jetzt bin ich aber gerade auf folgendes Problem dabei gestoßen:

    Programm starten -> IDR_xxxType-Menü wird angezeigt (kein Dokument offen, also sind alle irrelevanten Einträge deaktiviert) -> Dokument öffnen -> IDR_xxxType-Menü wird angezeigt (Einträge aktiviert) -> Dokument schließen -> IDR_MAINFRAME-Menü wird angezeigt (wobei hier wieder das IDR_xxxType-Menü angezeigt werden sollte.

    Hoffe ihr könnt mir folgen und versteht mein Problem.

    Jetzt komme ich eigentlich wieder zu meiner Ausgangsfrage dieses Threads:

    Wo genau findet der Wechsel zwischen den unterschiedlichen Menüs (IDR_xxxType (Dokument(e) geöffnet) / IDR_MAINFRAME (kein Dokument geöffnet)) im Programm statt? Kann beim besten Willen keine Stelle im Code finden, die das erledigt...

    Sorry, aber irgendwie fehlt mir zeitweise einfach noch der nötige Durchblick in c++ & mfc (hatte bisher Hauptsächlich mit C# und ein wenig Java zu tun).

    danke, mfg


Anmelden zum Antworten