CBitmapButton - ASSERT



  • N'abend ich hab ein kleines Problem mit CDialogBar und CBitmapButton

    Und zwar habe ich in einer SDI-Anwendung links ein CDialogBar erstellt
    mit einem Button mit der Bezeichnung OK. Die Button ID habe ich auf IDOK
    gelassen. Zusätzlich habe ich dem Button auf Benutzerdarstellung gesetzt.

    Weiterhin habe ich für diesen Button ein Bitmap in die Ressourcendatei
    importiert und habe dem Bitmap die Bezeichnung (ID) "OKN" gegeben.

    Dann habe ich gem. CodeGuru eine Abgeleitet Klasse für CDialogBar erstellt:

    //Headerdatei InitDlgBar.h
    #pragma once
    
    // CInitDlgBar
    
    class CInitDlgBar : public CDialogBar
    {
    	DECLARE_DYNAMIC(CInitDlgBar)
    
    public:
    	CInitDlgBar();
    	virtual ~CInitDlgBar();
    	BOOL Create(CWnd* pParentWnd,UINT nIDTemplate,UINT nStyle,UINT nID);
    
    protected:
    	virtual void DoDataExchange(CDataExchange *pDX);
    	virtual BOOL OnInitDlgBar();
    	DECLARE_MESSAGE_MAP()
    };
    
    //InitDlgBar.cpp
    
    #include "InitDlgBar.h"
    
    // CInitDlgBar
    
    IMPLEMENT_DYNAMIC(CInitDlgBar, CDialogBar)
    CInitDlgBar::CInitDlgBar()
    {
    }
    
    CInitDlgBar::~CInitDlgBar()
    {
    }
    
    BOOL CInitDlgBar::Create(CWnd* pParentWnd,UINT nIDTemplate,UINT nStyle,UINT nID)
    {
    	if(!CDialogBar::Create(pParentWnd,nIDTemplate,nStyle,nID))
    	{
    		return false;
    	}
    
    	if(!OnInitDlgBar())
    	{
    		return false;
    	}
    	return true;
    }
    
    BOOL CInitDlgBar::OnInitDlgBar()
    {
    	UpdateData(FALSE);
    	return true;
    }
    
    void CInitDlgBar::DoDataExchange (CDataExchange *pDX)
    {
    	ASSERT(pDX);
    	CDialogBar::DoDataExchange (pDX);
    }
    
    BEGIN_MESSAGE_MAP(CInitDlgBar, CDialogBar)
    END_MESSAGE_MAP()
    

    Nun folgt die Eigentliche Klasse für den DialogBar:

    #pragma once
    #include "InitDlgBar.h"
    
    // CToolMenue
    
    class CToolMenue : public CInitDlgBar
    {
    	DECLARE_DYNAMIC(CToolMenue)
    private:
    	CBitmapButton m_ok; //Das soll mein Bitmap Button werden!!!
    public:
    	CToolMenue();
    	virtual ~CToolMenue();
    
    protected:
    	virtual BOOL OnInitDlgBar();
    	virtual void DoDataExchange(CDataExchange *pDX);
    	DECLARE_MESSAGE_MAP()
    };
    
    #include "ToolMenue.h"
    
    // CToolMenue
    
    IMPLEMENT_DYNAMIC(CToolMenue, CInitDlgBar)
    CToolMenue::CToolMenue()
    {
    }
    
    CToolMenue::~CToolMenue()
    {
    }
    
    BOOL CToolMenue::OnInitDlgBar()
    {
    	CInitDlgBar::OnInitDlgBar();
    
            //Hier versuche ich den Button zu laden
            //und ich vermute, hier stimmt was nicht?????
    
    	m_ok.AutoLoad (IDOK,this); 
    	return true;
    }
    
    void CToolMenue::DoDataExchange (CDataExchange *pDX)
    {
    	ASSERT(pDX);
    	CInitDlgBar::DoDataExchange (pDX);
    }
    
    BEGIN_MESSAGE_MAP(CToolMenue, CInitDlgBar)
    END_MESSAGE_MAP()
    

    In CMainFrame.h habe ich dann statt CDialogBar bar;
    CToolMenue bar; implementiert.

    Nach dem Start der Anwendung erhalte ich nun aber sofort ein ASSERT
    mit dem Hinweis Line 103 winbtn.cpp ....

    Ich vermute ja es liegt an der CBitmapButton -> AutoLoad()...
    Naja, jedenfalls beschäftigt mich das schon 2 Tage lang und ich
    finde keine Lösung 🙄 🙄 🙄 😕

    Bitte schaut euch das doch mal an....ein langsam verzweifelter
    Hobbyprogrammierer.

    Danke!



  • ASSERT mit dem Hinweis Line 103 winbtn.h

    und was steht in der zeile?



  • Leider ist die Assert sehr wenig aussagend, das lediglich auf die Ziele
    103 in WinBtn.cpp verwiesen wird! (Die Datei gehört übrigens zur MFC und wurde nicht von mir eingebunden)

    Ich habe mal in dieser Datei (WinBtn.cpp) nachgesehen

    Der Assert wird bei CBitmapButton::OnDrawItem() ausgelöst und zwar hier:

    // Draw the appropriate bitmap
    void CBitmapButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
    {
    	ASSERT(lpDIS != NULL);
    
    	// must have at least the first bitmap loaded before calling DrawItem
    	ASSERT(m_bitmap.m_hObject != NULL);     // Hier wir der Fehler ausgelöst!!
    

    Aber ich verstehe es nicht, den das Bitmap müsste er doch haben??
    Ich habe zusätzlich zum o.a. Code noch LoadBitamps eingefügt,
    aber Fehlanzeige, wieder ein Assert mit dem Hinweis auf die gleiche
    Zeile

    BOOL CToolMenue::OnInitDlgBar()
    {
        CInitDlgBar::OnInitDlgBar();
    
        //Zusatz: Load Bitmap!
        m_ok.LoadBitmaps("OKN");
        m_ok.AutoLoad (IDOK,this);
        return true;
    }
    


  • Ist die Variable m_bitmap vom Typ CBitmap?

    Gruß
    :: NoName ::



  • Überprüf doch den Rückgabewert von AutoLoad. Ich wette die Funktion gibt FALSE zurück. 🤡



  • In der Tat, AutoLoad gibt FALSE zurück und m_Bitmap ist ein CBitmap.



  • Der Fehler lag in der Benennung des Bitmaps den sieht man sich mal die Funktion in der Original MFC (WinBtn.cpp) an:

    // Autoload will load the bitmap resources based on the text of
    //  the button
    // Using suffices "U", "D", "F" and "X" for up/down/focus/disabled
    BOOL CBitmapButton::AutoLoad(UINT nID, CWnd* pParent)
    {
    	....
    
    	LoadBitmaps(buttonName + _T("U"), buttonName + _T("D"),
    	  buttonName + _T("F"), buttonName + _T("X"));
    
    	// we need at least the primary
    	if (m_bitmap.m_hObject == NULL)
    		return FALSE;
            ...
    
           return TRUE;
    }
    

    so sieht man das wenn der Button z.B. OK heißt, dann sollte das Normale (für die Standardansicht) Bitmap "OKU" heißen. Bei mir hieß er aber "OKN"
    da ich versehntlicherweise irgendwie im Kopf hatte, dass N für Normal steht.
    Ist aber wieder typisch MS, wieso sollte man auch auf deutsche Schreibweise
    Wert legen.

    Danke an alle! Jetzt bin ich wieder froh 😃 😃 😃 😃


Log in to reply