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->Hersteller
    

    Rückgabewert gibt es keinen und laut Debugger sind alle Einträge in sIGBT leer.
    Deshalb gibt es einen Access Violation beim Aufruf von

    m_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?


Anmelden zum Antworten