Zeiger von Dialog zur Strukturelement
-
Servus,
ich habe mir ein Dialog erstellt, in dem sich ein TreeCtrl, ListCtrl und drei einzelne Eingabefelder befinden.
So weit klappts ja auch. Jetzt möchte ich Daten aus CChildView holen und damit das TreeCtrl und ListCtrl füllen.
Hier hakt es bei mir.
Zuerst hole ich mir einen Zeiger darauf. Über diesen Zeiger habe ich Zugriff auf das Objekt IGBT und das darunterliegende Objekt sIGBT. Nun möchte ich den Wert der Variable Hersteller vom Typ CString auslesen.view->IGBT->sIGBT->HerstellerRückgabewert gibt es keinen und laut Debugger sind alle Einträge in sIGBT leer.
Deshalb gibt es einen Access Violation beim Aufruf vonm_Auswahl_TREE.InsertItem( view->IGBT->sIGBT->Hersteller );In CChildView habe ich aber Zugriff auf die dort gespeicherten Werte.
Was mache ich falsch?CAuswahl::CAuswahl(CWnd* pParent /*=NULL*/) : CDialog(CAuswahl::IDD, pParent) { //{{AFX_DATA_INIT(CAuswahl) m_INFO_IGBT = _T(""); m_INFO_KK = _T(""); m_INFO_Lastspiel = _T(""); //}}AFX_DATA_INIT } void CAuswahl::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAuswahl) DDX_Control(pDX, IDC_Auswahl_TREE, m_Auswahl_TREE); DDX_Control(pDX, IDC_Auswahl_LIST, m_Auswahl_LIST); DDX_Text(pDX, IDC_INFO_IGBT, m_INFO_IGBT); DDX_Text(pDX, IDC_INFO_KK, m_INFO_KK); DDX_Text(pDX, IDC_INFO_Lastspiel, m_INFO_Lastspiel); //}}AFX_DATA_MAP Fuellen(); } BEGIN_MESSAGE_MAP(CAuswahl, CDialog) //{{AFX_MSG_MAP(CAuswahl) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // Behandlungsroutinen für Nachrichten CAuswahl CAuswahl::Fuellen() { CDC* pDC = GetDC(); CChildView* view = (CChildView*) pDC->GetWindow(); m_Auswahl_TREE.InsertItem( view->IGBT->sIGBT->Hersteller ); }
-
Zwei Dinge zum Code. Wenn du GetDC() aufrufst musst du am Ende auch ReleaseDC(pDC) aufrufen, da sonst Speicherlöcher entstehen. Zeile 37 gibt keine Zeiger auf ein CView Objekt (das Fenster) zurück sondern auf das Fenster CAuswahl.
Wie rufst du denn den Dialog CAuswahl auf?
-
GetWindow() gibt also handle auf aktuelles Fenster zurück. Wie komme ich dann an das Hauptfenster(also CChildView) ran?
void CMainFrame::OnAuswahl() { // TODO: Code für Befehlsbehandlungsroutine hier einfügen CAuswahl Auswahl; Auswahl.DoModal(); }
-
etsmart schrieb:
GetWindow() gibt also handle auf aktuelles Fenster zurück.
Nicht das aktuelle, sondern auf das dessen DC du mit GetDC geholt hast, denn du rufst ja pDC->GetWindow() auf.
etsmart schrieb:
Wie komme ich dann an das Hauptfenster(also CChildView) ran?
Du könntest die Methode DoModal in CAuswahl zum Beispiel überschreiben und ihr einen Zeiger auf CChildView geben.
// Header Datei private: CChildView *m_pChildView; // Privater Zeiger public: virtual INT_PTR DoModal(CChildView *pChildView); // CPP Date INT_PTR CAuswahl::DoModal(CChildView *pChildView) { // Hier hast du jetzt Zugriff auf die Member von CChildView this->m_pChildView = pChildView; }Anstatt die Methode DoModal zu überschreiben könntest du "es" auch mit der Methode CAuswahl::Fuellen machen. Anstatt bei DoModal den Zeiger zu übergeben, tust du das hier. Und bräuchtest ggf. auch keinen privaten Member auf CChilView.
-
Dann brauch ich aber den Zeiger von CMainFrm nach CChildView, da das Dialogfenster dort erstellt wird. Also das Gleiche wie vorher.
-
etsmart schrieb:
Dann brauch ich aber den Zeiger von CMainFrm nach CChildView, da das Dialogfenster dort erstellt wird. Also das Gleiche wie vorher.
Dann hol dir bevor du DoModal/Fuellen aufrufst den Zeiger auf CChildView und übergebe ihn dann.
-
Danke.
Öffnet Dialog
void CMainFrame::OnAuswahl() { // TODO: Code für Befehlsbehandlungsroutine hier einfügen // create objects Directory dir; CChildView* view = &m_wndView; // open dialog CAuswahl* Auswahl = new CAuswahl(); Auswahl->Create(IDD_Auswahl,this); Auswahl->ShowWindow(SW_SHOW); // fill treectrl with information dir.Read(&Auswahl->m_Auswahl_TREE,"./Projekt/*.*",0,0); }Liest Verzeichnis und füllt damit das CTreeCtrl
int Directory::Read(CTreeCtrl* ptrTreeCtrl,string path,HTREEITEM nItem,HTREEITEM nSubItem) { HTREEITEM nNewSubItem; CFileFind finder; BOOL bResult; string buffer,file; ptrTreeCtrl->ModifyStyle(NULL,TVS_HASBUTTONS | TVS_HASLINES | TVS_TRACKSELECT); bResult = finder.FindFile(path.c_str(),0); while(bResult) { bResult = finder.FindNextFile(); buffer = finder.GetFileName(); if(finder.IsDirectory()) { if(!finder.IsDots()) { nNewSubItem = ptrTreeCtrl->InsertItem(buffer.c_str(),nSubItem,nItem); file = finder.GetFilePath() + "/*.*"; Read(ptrTreeCtrl,file,nItem,nNewSubItem); } } else { if(nSubItem != 0) nItem = ptrTreeCtrl->InsertItem(buffer.c_str(),nSubItem,nItem); Filelist.resize(Filelist.size()+1); Filelist[Filelist.size()-1] = buffer.c_str(); } } return bResult; }
-
etsmart schrieb:
Danke.
Ich gehe mal davon aus das es jetzt klappt.

etsmart schrieb:
void CMainFrame::OnAuswahl() { // TODO: Code für Befehlsbehandlungsroutine hier einfügen // create objects Directory dir; CChildView* view = &m_wndView; // open dialog CAuswahl* Auswahl = new CAuswahl(); Auswahl->Create(IDD_Auswahl,this); Auswahl->ShowWindow(SW_SHOW); // fill treectrl with information dir.Read(&Auswahl->m_Auswahl_TREE,"./Projekt/*.*",0,0); }Falls das der ganze Code ist, gibts ein Speicherleck. Du musst die Variable Auswahl noch mit delete löschen. Wo wird denn jetzt view übergeben und warum erstellst du den Dialog dynamisch?