CMFCToolBar und Button disable



  • Hallo Zusammen,

    ich bin gerade am verzweifeln.
    Ich versuche ein meiner CMFCToolBar einen Button zu deaktivieren, wenn ich auf diesen drauf klicke.

    An sich funktioniert das deaktivieren von den Buttons, solange dieser Button nicht der ist, den ich gerade anklicke.
    Ich habe es bisher mit dieser Funktion ausgeführt:

    void CTestDlg::ChangeToolbarState(UINT id, BOOL value)
    {
    	int b_id = m_ToolBar.CommandToIndex(id);
    
    	if (value == TRUE) m_ToolBar.SetButtonStyle(b_id, TBSTATE_ENABLED | TBBS_BUTTON);
    	else m_ToolBar.SetButtonStyle(b_id, TBBS_DISABLED | TBBS_BUTTON);
    }
    

    Ich habs auch mit CCmdUI auf dem Button versucht, allerdings bekomme ich dann da immer eine Meldung im Output:

    void CTestDlg::OnUpdateTest(CCmdUI *pCmdUI)
    {
    
    	TraceString(_T("KLICK")); 
            pCmdUI->Enable(FALSE);
    }
    

    Meldung: "AppMsg - Warning: not executing disabled command 32869"

    Hat einer eine Idee was ich falsch mache oder geht es einfach nicht den Button, den ich gerade anklicke zu deaktivieren?

    Danke
    Uruk


  • Mod

    Du must einen Update Handler bauen.

    Der Trace ""AppMsg - Warning: not executing disabled command 32869" sagt Dir, aber dass Dein Update Handler nicht gefunden wird. Vermutlich liegt der nicht im Command Routing.

    Dein Updatehandler sitzt in einem Dialog? Hast Du also eine Dialogbasierende Anwendung? Wenn ja darfst Du ganz viel nachbauen. Toolsbars gehen dort nicht, wenn Du nicht die halbe CFrameWnd Klasse nachbaust..

    http://blog.m-ri.de/index.php/2008/09/07/die-unsitte-dialogbasierende-anwendungen-zu-bauen-statt-sdi-mit-cformview-zu-verwenden/



  • Ja ich habe eine dialogbasierte Anwendung.
    Und die Toolbar läuft eigentlich ganz gut. Nur das Problem mit dem Deaktivieren des gerade angeklickten Buttons läuft nicht.
    Zur verdeutlichung, ich habe unter anderem 2 Buttons in der Toolbar, einen zum Verbinden und einen zum Trennen. Die Sollen sich gegenseitig Enablen/Disablen und sich selbst dann auch. Und das "sich selbst auch" wird nicht ausgeführt, bzw. hat keine Wirklung.

    Aber wenn es nicht in den DLG Anwendungen vorhanden ist, muss ich damit leben und einen andere Weg finden. Umstellen auf eine SDI ist leider nicht möglich.

    Trotzdem Danke 😃


  • Mod

    Klar ist umstellen auf SDI mit Form View möglich.

    Ansonsten gibt es auch dazu Code.
    http://www.codeproject.com/Articles/2685/Toolbar-StatusBar-on-Dialog



  • Naja klar ist das Umstellen möglich, wenn man Zeit hätte 😉 Es sind immer die kleinen wünsche am Ende eines Projektes, die alles kompliziert machen...

    Ich habs jetzt erstmal anders gelöst um die zwei besagten Toolbar Buttons zu Aktivieren/Deaktivieren, mit WM_KICKIDLE. Funktioniert super, auch wenn es nicht die schönste Lösung ist.



  • Hi,

    es gibt erhebliche Probleme ohne dem dazugehörigen Framework.

    Inzwischen verwende ich CToolBar und alles ist gut. Selbst wenn
    es funktiniert ergibt es Memory Leaks bezüglich irgendwelcher
    resourcen die da dynamisch allokiert werden.

    Auch gibt es Probleme mit ToolTips bei der CMFCToolBar

    Hier zb die unterschiedliche handhabe bei OnNeedText

    BOOL CPatControlDlg::OnNeedText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
    {
    	/*
    	//CMFCToolBar
    	UINT_PTR nId = pNMHDR->idFrom - 1;
    	CMFCToolBarButton *pBtn = m_ToolBar.GetButton(nId);
    	if(pBtn)
    	{
    		TCHAR szBuff[64];
    		LoadString(AfxGetResourceHandle(), pBtn->m_nID, szBuff, sizeof(szBuff) / sizeof(TCHAR));
    		TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
    		pTTT->lpszText = szBuff;
    		pTTT->hinst = AfxGetResourceHandle();
    	}*/
    
    	//CToolBar
    	if(m_ShowToolTip)
    	{
    		NMTOOLBAR* pNMToolBar = (NMTOOLBAR*)pNMHDR;
    		TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
    		UINT_PTR nId = pNMHDR->idFrom;
    		TCHAR szBuff[128]; LoadString(AfxGetResourceHandle(), nId, szBuff, sizeof(szBuff) / sizeof(TCHAR));
    		pTTT->lpszText = szBuff;
    		pTTT->hinst = AfxGetResourceHandle();
    	}
    
    	return TRUE;
    }
    

    Fazit: nur verwenden wenn SDI oder MDI Anwendungen mit dem
    verwendeten Framework des Klassen-Assistenten erstellt wurden.

    Grüße
    Karsten


Log in to reply