Control-Variablen als Array
-
Aber ich vergebe doch normalerweise Namen. Die Zahlen werden doch dann intern vom Compiler vergeben, oder...?
Die Control-Variable selbst ist nicht als array möglich?
-
Du kannst auch ein CArray<CButton, CButton> machen.
-
estartu_de schrieb:
Du kannst auch ein CArray<CButton, CButton> machen.
Etwas in Richtung
CButton ButtonControl[0] für Button0
CButton ButtonControl[1] für Button1
.
.
.geht nicht? Ich meine, unter Visual Basic habe ich mal sowas gemacht...
-
Das kannst du so machen:
CArray<CButton*, CButton*> m_arrButtons; // Ohne * geht bestimmt auch, aber nicht so einfach. //Und dann in OnInit... m_arrButtons.Add(GetDlgItem(IDC_BTN1)); m_arrButtons.Add(GetDlgItem(IDC_BTN2)); //usw.
-
Cool, danke!
-
tronaccount schrieb:
Aber ich vergebe doch normalerweise Namen. Die Zahlen werden doch dann intern vom Compiler vergeben, oder...?
Die Control-Variable selbst ist nicht als array möglich?
weiss nicht ob ein Compiler nr. vergibt, ich glaubs aufjedenfall nicht.
wenn du mit mfc was erstellt, vergibts du ja normalerweise einen aussagelkräftigen namen. in der resource datei stehen ja dann all diese namen mit der nr drin. jetzt kannst du die nummer beliebig ändern, darf halt keine nummer 2mal vorkommen. eh klar.
du kannst auch eigenes "system" machen.
radiobuttons fangen mit 10xx an
ne textbox mit 20xx oder dann 21xx fuer den nächsten dialog(wenn mehrere)viel spass beim ausprobieren.
-
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:
stattm_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!