Debug Assertion failed - winctrl2.cpp
-
void PropertyPageSeiteA::OnButtonScriphandling() { CScript dlgScript; dlgScript.m_seiteA = this; dlgScript.DoModal(); }
Durch das this weise ich ja dem m_seitA zu, wohin es zeigen soll. Nun hab ich aber noch 10 weitere Seiten, denen ich Daten zuweisen will. Da ich aber nur aus einer Seite von CPropertyPage den Dialog CSript aufrufe, kann ich ja mit this nur auf eine Seite zurückverweisen.
Nun versuche ich also die Zeiger auf die existierenden Instanzen m_seiteB bis m_seiteJ ebenfalls zu übergeben. Und das stellt mich halt vor das Probelm, das ich wiedermal ned weis wie... Ja, ich weis, Basiswissen, welches ich aber nicht habe...
Analog zu dem oben, muss ich ja nun ihm noch erklären, wo er den Rest herbekommt, also:
dlgScript.m_seiteB = this;
Was natürlich Blödsinn ist, weil ich ja mich im Moment in der Seite A befinde. Also muss die Lösung anders aussehen. (Wieso funzt die Suche nie, wenn man sie zum quoten braucht... GRH)
PropertyPageSeiteB* m_seiteB= new PropertyPageSeiteB();
Dieser Ansatz fällt ja aus, weil ich ja den Zeiger auf die bestehende Instanz brauche, nicht auf eine hier erzeugte neue.
Also quasi folgende Form, was so aber nicht korrekt ist. (Fehler C2440)
dlgScript.m_seiteB = IDD_PROPPAGE2;
-
Ah, gefunden, was ich gesucht hab... in einem anderen Beitrag ist noch dies hier vermerkt:
CModelldesignerView* pMDView = (CModelldesignerView*)this->GetActiveView();
Wenn ich versuche das zu machen, hab ich wieder das Problem von this. In der kommenden Fehlermeldung verweist er a) auf PropertyPageSeiteA und b) darauf, das GetActiveView nicht existiert.
lässt sich ja erklären, weil eine Funktion, die nicht enthalten ist, kann ich nunmal nicht verwenden. Nur ist a) dann wieder das Problem, weil ich ja auf PropertyPageSeiteB zugreifen will.
--------------------Configuration: HDTV_MIC - Win32 Debug--------------------
Compiling...
PropertyPageSeiteA.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\HDTV_MIC\PropertyPageSeiteA.cpp(1378) : warning C4101: 'buffer' : unreferenced local variable
C:\Program Files\Microsoft Visual Studio\MyProjects\HDTV_MIC\PropertyPageSeiteA.cpp(1640) : warning C4101: 'buffer' : unreferenced local variable
C:\Program Files\Microsoft Visual Studio\MyProjects\HDTV_MIC\PropertyPageSeiteA.cpp(2292) : error C2039: 'GetActiveView' : is not a member of 'PropertyPageSeiteA'
c:\program files\microsoft visual studio\myprojects\hdtv_mic\propertypageseitea.h(14) : see declaration of 'PropertyPageSeiteA'
-
Von wo werden die Seiten den erstellt? Ich denke, dort musst du ansetzen.
-
Die Seiten werden noch nen Dialog tiefer erstellt halt
Ist ja nunmal ne Dialogbasierende Anwendung. Sekunde...
void CHDTV_MICDlg::OnButtonStart() { PropertyPageSeiteA propertyPageSeiteA; PropertyPageSeiteB propertyPageSeiteB; PropertyPageSeiteC propertyPageSeiteC; PropertyPageSeiteD propertyPageSeiteD; PropertyPageSeiteE propertyPageSeiteE; PropertyPageSeiteF propertyPageSeiteF; PropertyPageSeiteG propertyPageSeiteG; PropertyPageSeiteH propertyPageSeiteH; PropertyPageSeiteI propertyPageSeiteI; PorpertyPageSeiteJ propertyPageSeiteJ; PropertyPageSeiteK propertyPageSeiteK; CMyPropSheet propertySheet("Titel", this); propertySheet.AddPage(&propertyPageSeiteA); propertySheet.AddPage(&propertyPageSeiteB); propertySheet.AddPage(&propertyPageSeiteC); propertySheet.AddPage(&propertyPageSeiteD); propertySheet.AddPage(&propertyPageSeiteE); propertySheet.AddPage(&propertyPageSeiteF); propertySheet.AddPage(&propertyPageSeiteG); propertySheet.AddPage(&propertyPageSeiteH); propertySheet.AddPage(&propertyPageSeiteI); propertySheet.AddPage(&propertyPageSeiteJ); propertySheet.AddPage(&propertyPageSeiteK); propertySheet.DoModal(); }
Am schönsten wärs wahrscheinlich, ich käme an das CPropertySheet ran, von da müsste ich ja an dessen Seiten kommen.
-
Ist das zufällig der Hauptdialog? Dann wäre es nämlich deutlich einfacher als sonst.
Denn da ich leider nicht weiß, ob das PropertySheet seine Seiten kennt und umgekehrt, müsste man da tricksen.
-
Ja, ist er sogar
Ist jedenfalls der erste, der geöffnet wird
-
Okay, dann starte mal folgenden Umbau:
PropertyPageSeiteA propertyPageSeiteA; PropertyPageSeiteB propertyPageSeiteB; PropertyPageSeiteC propertyPageSeiteC; PropertyPageSeiteD propertyPageSeiteD; PropertyPageSeiteE propertyPageSeiteE; PropertyPageSeiteF propertyPageSeiteF; PropertyPageSeiteG propertyPageSeiteG; PropertyPageSeiteH propertyPageSeiteH; PropertyPageSeiteI propertyPageSeiteI; PorpertyPageSeiteJ propertyPageSeiteJ; PropertyPageSeiteK propertyPageSeiteK;
Pack das mal in den Header, als public. (Im Cpp natürlich löschen.)
Dann solltest du von CScript aus so drankommen:
PropertyPageSeiteB* pPageB = &(((CHDTV_MICDlg*)AfxGetMainWnd())->propertyPageSeiteB);
Das ist aus dem Kopf getippt, müsste aber gehen.
Wenn das klappt, kannst du auch die anderen Seiten so bekommen.Das ist noch nicht die saubere Lösung, aber an die können wir uns machen, wenn das da geht.
-
Mh, wir drehen uns im Kreis
CWnd* CWnd::GetDlgItem(int nID) const
{
ASSERT(::IsWindow(m_hWnd));if (m_pCtrlCont == NULL)
return CWnd::FromHandle(::GetDlgItem(m_hWnd, nID));
else
return m_pCtrlCont->GetDlgItem(nID);
}Hängt wieder am Assert
Würde uns zu Seite 1 des Threads führen, wo MFK festgestellt hat, dass wir grade auf die falsche Stelle zeigen... ich versuchs mal mit der SeiteA anstelle B. Wenn er die beschreiben kann mit deiner Konstruktion hab ich glaub nen grösseres Problem.
Jepp, so mag ers ned. Im Skripthandling:
PropertyPageSeiteA* pPageA = &(((CHDTV_MICDlg*)AfxGetMainWnd())->propertyPageSeiteA); CListCtrl* mList = (CListCtrl*) pPageA->GetDlgItem(IDC_LIST1); mList->SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT); mList->SetItemText(0, 3, "FF"); PropertyPageSeiteB* pPageB = &(((CHDTV_MICDlg*)AfxGetMainWnd())->propertyPageSeiteB); CListCtrl* nList = (CListCtrl*) pPageB->GetDlgItem(IDC_LIST1); nList->SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT); nList->SetItemText(0, 3, "FF");
Zugriff auf Die SeiteA ist vorhanden, bei SeiteB obige Meldung. Oh... Sekunde, hab noch was entdeckt, kommt gleich noch was nach eventuell.
-
Habs, zumindest das, was den Fehler produziert. Der sollte sich umgehen lassen.
Wenn ich das Programm aufrufe, so liegt beim PropertySheet automatisch die SeiteA oben, da sie die erste ist. Rufe ich das Skripthandling auf und löse die beschriebene Funktion auf, kippt er mich mit der genannten Fehlermeldung raus.
Neuer Versuch. Wieder Programmstart. PropertySheet SeiteA liegt oben, ich klicke B an und kehre danach wieder auf A zurück. Nun geht es und er trägt in beide CListCtrls ein.
D.h. also im Umkehrschluss für mich:
-es wird beim Aufruf der PropertySheet nur die obenliegende Page automatisch geöffnet und somit deren OnInitDialog durchgeführt, da dort die Liste erzeugt wird
-so dass ich also erstmal alle Fenster durchklicken müsste vom PropertySheet um keinen Fehler zu produzieren, der mich kickt.Folgerung-> Also Funktion suchen, die alle Fenster nach und nach durchgeht, so dass alle ihren OnInitDialog abgelaufen haben, und diese im Aufruf des PropertySheets verankern.
-
OnInitDialog reagiert doch auf eine Nachricht... WM_INITDIALOG
Ein PropertyPage ist ein Fenster...
Einem Fenster kann man eine Nachricht schicken.Teste mal:
propertySheet.AddPage(&propertyPageSeiteA); propertySheet.AddPage(&propertyPageSeiteB); propertyPageSeiteB.SendMessage(WM_INITDIALOG);
Ist nur ne Idee, keine Ahnung ob es geht.
-
Mh, ne, da steht er ned drauf, aber auf meine Ideen auch noch ned
Dein Ergebnis
_AFXWIN_INLINE LRESULT CWnd::SendMessage(UINT message, WPARAM wParam, LPARAM lParam)
{ ASSERT(::IsWindow(m_hWnd)); return ::SendMessage(m_hWnd, message, wParam, lParam); }Meine Ideen waren bisher:
propertySheet.ExecuteDlgInit(&propertyPageSeiteA);
oder
propertySheet.SetActivePage(&propertyPageSeiteA); propertySheet.SetActivePage(&propertyPageSeiteB); propertySheet.SetActivePage(&propertyPageSeiteA);
Proudziert wieder alles nur Fehler
-
Kommt schon, irgendwer noch nie Idee? Es kann doch nicht Sinn und Zweck sein, erst alle 11 PropertyPages durchklicken zu müssen, bevor ich dann ohne Ausnahmefehler in die Teile schreiben kann, weil sie erst nach einmal anklicken initialisiert worden sind...
Ich brauche doch "nur" einen Befehl, der die Teilie alle initialisiert und auch noch dabei funktioniert
-
Ich weiß keinen, sorry.
-
Heisst die Fehlermeldung ich schicke an ein nichtexistierendes Obejkt oder ich hab den falschen Absender?
_AFXWIN_INLINE LRESULT CWnd::SendMessage(UINT message, WPARAM wParam, LPARAM lParam)
{ ASSERT(::IsWindow(m_hWnd)); return ::SendMessage(m_hWnd, message, wParam, lParam); }
-
Ersteres, du hast keinen Empfänger.
-
warum machst du dir nicht eine Klasse zur Datenhaltung anstatt alles in die Pages einzutragen. Klick dann einer auf die Page dann kannst du die Daten in die Page laden.
So wie es bei DOC/VIEW ist.
Du kannst die Daten auch in eine Variable der Pageklasse schreiben und beim Klick dann ins Steuerelelemt laden.
-
Hab die Lösung
Im Hauptdialog wird PropertySheet aufgerufen:
void CHDTV_MICDlg::OnButtonStart() { CMyPropSheet propertySheet("Titel", this); propertySheet.AddPage(&propertyPageSeiteA); propertySheet.AddPage(&propertyPageSeiteB); propertySheet.AddPage(&propertyPageSeiteC); propertySheet.AddPage(&propertyPageSeiteD); propertySheet.AddPage(&propertyPageSeiteE); propertySheet.AddPage(&propertyPageSeiteF); propertySheet.AddPage(&propertyPageSeiteG); propertySheet.AddPage(&propertyPageSeiteH); propertySheet.AddPage(&propertyPageSeiteI); propertySheet.AddPage(&propertyPageSeiteJ); propertySheet.AddPage(&propertyPageSeiteK); propertySheet.DoModal(); }
Anstatt nun, wie dein Ansatz, zu versuchen den InitDialog mit Messages oder sonstigen Befehlen zu initieren aus anderen Dialogen heraus, gehst nun in den Dialog PropertySheet selsbt rein, in dessen OnInit-Anweisung und schaltest dort die Seiten einmal alle durch, so dass sie gezwungenermassen sich initialisieren.
BOOL CMyPropSheet::OnInitDialog () { BOOL bResult = CPropertySheet::OnInitDialog(); int ids [] = {IDOK, IDCANCEL};//, ID_APPLY_NOW, IDHELP }; // Hide Apply and Help buttons CWnd *pWnd = GetDlgItem (ID_APPLY_NOW); pWnd->ShowWindow (FALSE); pWnd = GetDlgItem (IDHELP); pWnd->ShowWindow (FALSE); pWnd = GetDlgItem (IDCANCEL); pWnd->ShowWindow (FALSE); pWnd = GetDlgItem (IDOK); pWnd->ShowWindow (FALSE); SetActivePage(0); SetActivePage(1); SetActivePage(2); SetActivePage(3); SetActivePage(4); SetActivePage(5); SetActivePage(6); SetActivePage(7); SetActivePage(8); SetActivePage(9); SetActivePage(10); SetActivePage(0); return bResult; }
Versuchst du diesen Trick im Aufruf oben, geht er schief, da dort nur die letzte Zeile (hier SetActivePage(0)) abgearbeitet wird, da das Ganze ja erst danach modal wird. Machst es hingegen im PropertySheet, frisst er es, da das Ganze nun modal ist.
Meine Güte... komplizierter gings kaum.
-
Wäre sicher ne Alternative gewesen, hät das Ganze nun ned funktioniert
Ziel ist halt, das der User nicht nur Skripte verschickt, sondern auch sieht, was er verschickt hat ohne es nachladen zu müssen
Viele Wege führen nach Rom