Control-Variablen als Array



  • Hallo nochmal.

    Ich habe das mal implementiert:

    // Attribute
    class CCommandPane : public CFormView
    {
    ...
    public:
    	CArray<CButton*,CButton*> m_1xButtonArray;
    ...
    }
    

    Dann in der OnInitialUpdate()

    void CCommandPane::OnInitialUpdate() 
    {
    m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_U));
    	m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_V));
    	m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_CHI));
    	m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_KAPPA));
    	m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_F));
    	m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_M));
    	m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_PHI));
    	m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_NOTHING));
    	m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_SCALE1X));
    	m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_SCALE1XDISPLAY));
    	m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_BORDER));
    	m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_TEXT_1X));
    }
    

    Wenn ich jetzt versuche, in der OnUpdate() Werte zuzuweisen, bekomme ich einen "Debug Assertion failed!"-Fehler:

    void CCommandPane::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
    {
    	// TODO: Speziellen Code hier einfügen und/oder Basisklasse aufrufen
    
    		m_1xButtonArray[0]->EnableWindow(TRUE);
    	}
    }
    

    Rufe ich denselben Befehl direkt in der OnInitialUpdate() nach Erstellen des Arrays auf, klapt alles 😞

    Ich will aber regelmäßig die Buttons enablen/disablen. Eigentlich wird doch die OnInitialUpdate() nur bei der ersten Update-WM aufgerufen, danach sowieso nur noch OnUpdate() - wo liegt denn da das Problem?



  • Tu dir beim Nutzen eines CArray den Gefallen und nutze die GetAt Funktion - die hat eine Bereichsprüfung drin, die die [] nicht haben.

    Ich vermute, dass das Array beim ersten Update nicht gefüllt ist. Bau doch noch eine passende if ein und gut ist. 🙂



  • Danke für den GetAt()-Tip. Habe ich implementiert. Leider hatte ich die Überprüfung bereits eingebaut:

    CCommandPane::CCommandPane()
    	: CFormView(CCommandPane::IDD)
    {
    	//{{AFX_DATA_INIT(CCommandPane)
    	m_CSpeedValue = 0;
    	m_CTimeValue = 0;
    	//}}AFX_DATA_INIT
    
    	arrayCreated = FALSE;
    }
    

    und dann:

    void CCommandPane::OnInitialUpdate() 
    {
    ...
    m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_U));
    m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_V));
    m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_CHI));
    ...
    arrayCreated = TRUE;
    }
    

    und in der OnUpdate dann:

    void CCommandPane::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
    {
    if (arrayCreated = TRUE) m_1xButtonArray.GetAt(0)->EnableWindow(FALSE);
    }
    

    Bringt leider gar nichts. Schmiert mit demselben Assertion-Fehler ab... 😕



  • Drück beim ASSERT mal Wiederholen und zeig die Funktion und die Stelle wo er steht.

    Edit: Statt der bool-Variablen hättest du doch auch einfach nach der Größe des Arrays gucken können. Das geht mit GetSize(). 🙂



  • Geht nicht. Es kommt sofort diese WinXP-Fehlerreport-Box danach als Modales Fenster. Wenn ich die schließe, ist die Assertion-Box auch weg...

    Findet jemand einen Fehler im geposteten Code?



  • ...habe mal etwas gespielt. Beim Debuggen lande ich in der Disassemblierung (!?!) und hier fliegt er in der letzten Zeile raus...

    .
    .
    .
    326:          return m_pCtrlSite->EnableWindow(bEnable);
    5F436D8A   mov         ecx,dword ptr [bEnable]
    5F436D8D   push        ecx
    5F436D8E   mov         edx,dword ptr [this]
    5F436D91   mov         ecx,dword ptr [edx+3Ch]
    5F436D94   mov         eax,dword ptr [this]
    5F436D97   mov         edx,dword ptr [eax+3Ch]
    5F436D9A   mov         eax,dword ptr [edx]
    

    Scheint was mit dem Enablen und nicht so sehr mit dem CArray zu tun haben, was!?

    Achso, nochwas. Wenn ich direkt nach dem Belegen des Arrays in der OnInitialUpdate die Buttons enable/disable, so klappt das ja zunächst. Wenn ich dann aber eine Datei öffne (also die Serialize()-Funktion des Dokuments aufrufe), so fliegt das Ganze wieder raus... hmmmppff!



  • Mir ist aufgefallen, das du dich sehr auf deine Zeigerinhalte verläßt. Das kann zu solchen Fehlern führen, wie du gerade suchst.

    Korrekturvorschläge:
    statt

    m_1xButtonArray.Add((CButton*)GetDlgItem(IDC_1X_U));
    
    m_1xButtonArray.Add(dynamic_cast<CButton*>(GetDlgItem(IDC_1X_U)));
    

    und statt

    if (arrayCreated = TRUE) m_1xButtonArray.GetAt(0)->EnableWindow(FALSE);
    
    if ((arrayCreated == TRUE) && (m_1xButtonArray.GetAt(0) != NULL)) m_1xButtonArray.GetAt(0)->EnableWindow(FALSE);
    

    Man kann das übrigens auch kürzen:

    if ((arrayCreated) && (m_1xButtonArray.GetAt(0))) m_1xButtonArray.GetAt(0)->EnableWindow(FALSE);
    

    Wenn du vor jeder Zeigerbenutzung eine entsprechende if einbaust, solltest du den Absturz verhindern können. Nur den Grund müßte man noch finden, aber das wird dann auch einfacher, weil du weißt WELCHER Zeiger Mist war. 🙂

    Edit: Urgs, habe gerade einen bösen Fehler in deinem Quelltext gefunden:

    if (arrayCreated = TRUE)
    

    da muss doch ein Doppelgleich hin! ⚠



  • m_1xButtonArray.Add(dynamic_cast<CButton*>(GetDlgItem(IDC_1X_U)));
    
    if ((arrayCreated == TRUE) && (m_1xButtonArray.GetAt(0) != NULL)) m_1xButtonArray.GetAt(0)->EnableWindow(FALSE);
    

    Danke, habe ich gemacht. Dummerweise kommt die if-Bedingung jetzt nichtz mehr zur Ausführung - werde das mal checken.

    Urgs, habe gerade einen bösen Fehler in deinem Quelltext gefunden:

    if (arrayCreated = TRUE)
    

    da muss doch ein Doppelgleich hin! ⚠

    Stimmt! Habe ich bei dem Gebastel falsch gemacht - ändert aber nichts am Fehler. Trotzdem Danke für die Tips!

    Falls das nicht klappen sollte, werde ich vielleicht doch eine Schleife über die ID's laufen lassen und direkt mit GetDlgItem(IDC_XXX) arbeiten. Die ID's sind doch in der resource.h festgelegt - darf ich die int-Werte für die ID's editieren, oder gibt's dann Probleme? Sind doch eigentlich nur DEFINE's, oder?



  • Die kannst du ändern,musst du nur drauf achten das es keine doppelten gibt.



  • Habe ich gemacht. Scheint zu klappen. Danke an alle!


Anmelden zum Antworten