Speichern



  • Guten Tag
    ich möchte in meinem Programm (SDI-Anwendung) den Benutzer über ein Dialogfenster ein paar Daten abfragen z.b.den Wohnort oder seinen Namen. Diese Informationen sollen gespeichert werden und beim nächsten aufruf des Dialogfeldes wieder angezeigt werden.
    Ich habe schon einen Menübefehl eingefügt über den man das Dialogfenster aufrufen kann und das klappt auch alles ohne Probleme.
    Doch werden die eingegebenen Daten einfach nicht gespeichert.
    Ich habe mir schon in dem Buch "Visual C++ in 21 Tagen" das Kapitel Dateizugriff durch gelesen, doch werden hier die Daten im Anwendungfenster eingegeben und dort wieder angezeigt. Ich kann diese Informationen einfach nicht auf das Dialogfeld umsetzen.
    Ich wäre euch sehr dankbar wenn ihr mir genau erklären könntet was ich machen muss sodass die Daten im Dialogfenster gespeichert und wieder angezeigt werden.
    Wenn ihr die Zeit habt könnt ihr auch eine einfach anwendung mit Visual c++ schreiben wo z.b. im Dialogfenster nur eine Sache(z.b. Wohnort) abgefragt wird.
    Auf jeden Fall schon mal Herzlichen Dank



  • Wo liegt das Problem?
    Speichern und lesen kannst du doch mit CStdioFile machen !?

    Am besten zu speicherst die einzelnen Daten in der Reihenfolge unterenander wie deine Editboxen sind. Dann kannst du beim nächsten mal die gleiche Reihenfolge zum einlesen benutzen.

    Hoffe du kommst klar



  • Hört sich gut an kannst du mir vielleicht auch ein Beispiel zeigen wie du CStdioFile benutzt?



  • Also schreiben...

    CStdioFile OutFile; 
    if (OutFile.Open("C:\\Data.txt", CFile::modeCreate | CFile::modeWrite)) 
    { 
       OutFile.WriteString(m_strEingabe); // Variable einer Editbox
       OutFile.Close(); 
    }
    

    Und lesen...

    CString strReadBuffer;
    
    CStdioFile ReadFile;
    if(ReadFile.Open("C:\\Data.txt", CFile::modeRead))
    {
       while(ReadFile.ReadString(strReadBuffer))
       {
          AfxMessageBox(strReadBuffer); //Zeilenweise alle Einträge
       }
    }
    

    Beim schreiben musst du nur alle deine daten in einen String packen und ihn
    dann speichern...



  • Als ich deinem Vorschlag nachgegangen bin ist ein weiteres Problem entstanden, nämlich das ich ja alle daten aus dem Dialogfenster in einer bestimmten Klasse (Daten) habe, wie es auch üblich ist. Doch der Aufruf des Dialogfensters ist in der CTestDApp.

    void CTestDApp::OnHalloDaten()
    {
      // TODO: Fügen Sie hier Ihren Befehlsbehandlungscode ein.
      CDaten Daten;
      if (Daten.DoModal() == IDOK)
        {
          CStdioFile OutFile; 
          if (OutFile.Open("C:\\Data.txt", CFile::modeCreate | CFile::modeWrite)) 
    	{ 
    	   OutFile.WriteString(m_sText); // Variable einer Editbox 
    	   OutFile.Close(); 
    	} 
         }
    }
    

    Hierdurch ergibt sich ein kleines Problem nämlich dass die Datei m_sText in dieser Klasse nicht deklariert ist, sondern nur in der Klasse Daten
    Ich habe zwar schon am Anfang der CTestDApp die include Anweisung "Daten.h" eingegeben doch m_sText ist immer noch nicht deklariert.
    Was muss ich tun damit sich dieses Problem behebt?
    Mfg 123Kobold



  • wie wäre es mit:

    OutFile.WriteString(Daten.m_sText);
    

    😕



  • Gibt noch ein Problem, wenn ich in m_sText z.b. A eingebe und in m_sText2 z.b. B eingebe, dann wird beim öffnen des Fensters nicht in das eine Eingabefeld A und in das andere B angezeigt, sondern in beiden erscheint AB.
    Hier ist der Code der fürs einlesen zuständig ist:

    void CTestDApp::OnHalloDaten()
    {
    	// TODO: Fügen Sie hier Ihren Befehlsbehandlungscode ein.
    	CDaten Daten;
    	if (Daten.DoModal() == IDOK)
    	{
    		CStdioFile OutFile; 
    		if (OutFile.Open("C:\\Data.txt", CFile::modeCreate | CFile::modeWrite)) 
    		{ 
    			OutFile.WriteString(Daten.m_sText); // Variable einer Editbox 
    			OutFile.WriteString(Daten.m_sText2);
    
    			OutFile.Close(); 
    		} 
    	}
    }
    

    Der Code zum anzeigen:

    CDaten::CDaten(CWnd* pParent /*=NULL*/)
    	: CDialog(CDaten::IDD, pParent)
    	, m_sText(_T(""))
    	, m_sText2(_T(""))
    {
    	CString strReadBuffer; 
    
    	CStdioFile ReadFile; 
    	if(ReadFile.Open("C:\\Data.txt", CFile::modeRead)) 
    		{ 
                while(ReadFile.ReadString(strReadBuffer)) 
                    {
    					m_sText=strReadBuffer;	
    					m_sText2=strReadBuffer;
    
                        //AfxMessageBox(strReadBuffer); //Zeilenweise alle Einträge 
    
    				} 
    		} 
    }
    

    Ich hoffe ihr könnt mir weiter helfen, sodass die beiden Texte nicht mehr hintereinander geschrieben werden, sondern jeder in seinem Eingabefeld angezeigt wird.



  • 123Kobold schrieb:

    ....
                while(ReadFile.ReadString(strReadBuffer)) 
                    {
    					m_sText=strReadBuffer;	
    					m_sText2=strReadBuffer;
    
                    } 
    		 
    ....
    

    Hier liegt der Fehler. Du liest in der While-Schleife "A" ein und gibst diesen Character an m_sText und m_sText2 weiter!
    21ner's hatte den Vorschlag, dass du das Lesen und Schreiben in der Reihenfolge gleich der Tabreihenfolge deiner Elemente durchführst. Somit müsste es ja möglich sein, eine For-Schleife zu programmieren und anhand der Position den aktuell eingelesenen String in das richtige Element zu schreiben.
    😉



  • Hört sich gut an Paul_C. wie soll ich das mit der For-Schleife machen. Könntest du oder jemand mir den Code ziegen, denn ich weis nicht wie ich das mit dem abfragen der Positionen machen soll.



  • Das ist eigentlich nicht schwer, wenn man weiss wie, es geht. 😉

    CEdit* pStartEdit = (CEdit*) GetDlgItem(ID_EDIT1); //Zeiger auf erste EditBox
    CEdit* pEndEdit=(CEdit*)GetDlgItem(ID_EDIT2);//Zeiger auf lezte EditBox
    int startID = pstartEdit->GetDlgCtrlID();
    int endID   = pendEdit->GetDlgCtrlID();
    
    for (int i = startID; i<= endID; i++)
    {
        ReadFile.ReadString(strReadBuffer);
        CEdit* pEdit = (CEdit*) GetDlgItem(i);
        pEdit->SetWindowText(strReadBuffer);
    }
    

    Das wäre eine Idee,die mir so einfällt.
    Eine andere:

    CEdit* pEdit = (CEdit*) GetDlgItem(ID_EDIT1);// erste EditBox
    if (pEdit)                                        // überprüfen, ob vorhanden
    {
        do
        {
            ReadFile.ReadString(strReadBuffer);       // String einlesen
            pEdit->SetWindowText(strReadBuffer);      // Text setzen
            pEdit = (CEdit*)GetNextDlgTabItem(pEdit); // Zeiger auf nächste Box setzen
        {
        while (pEdit != NULL);                        
    }
    

    Ich bin natürlich davon ausgegangen, dass du nur EditBoxen nutzt. 😉
    Ach ja, ich habe diese Beispiele nicht ausprobiert. Falls es Probleme gibt, dann melde dich.



  • Paul_C ich habe deine Vorschläge ausprobiert und folgende Fehlermeldungen erhalten. Hier ist der Code zum ersten Vorschlag und dessen Fehlermeldungen. Ich hoffe du kannst mir weiter helfen.
    Code:

    CDaten::CDaten(CWnd* pParent /*=NULL*/)
    	: CDialog(CDaten::IDD, pParent)
    	, m_sText(_T(""))
    	, m_sText2(_T(""))
    {
    	CString strReadBuffer; 
    
    	CStdioFile ReadFile; 
    	if(ReadFile.Open("C:\\Data.txt", CFile::modeRead)) 
    		{
    			CEdit* pStartEdit = (CEdit*) GetDlgItem(IDC_EDIT1); //Zeiger auf erste EditBox 
    			CEdit* pEndEdit=(CEdit*)GetDlgItem(IDC_EDIT2);//Zeiger auf lezte EditBox 
    			int startID = pstartEdit->GetDlgCtrlID(); 
    			int endID   = pendEdit->GetDlgCtrlID(); 
    
    			for (int i = startID; i<= endID; i++) 
    			{ 
    				ReadFile.ReadString(strReadBuffer); 
    				 CEdit* pEdit = (CEdit*) GetDlgItem(i); 
    				pEdit->SetWindowText(strReadBuffer); 
    			} 
    		}
    }
    

    Fehlermeldungen:
    error C2065: 'pstartEdit': nichtdeklarierter Bezeichner
    error C2227: Der linke Teil von '->GetDlgCtrlID' muss auf Klasse/Struktur/Union zeigen Typ ist ''unknown-type''
    error C2065: 'pendEdit': nichtdeklarierter Bezeichner
    error C2227: Der linke Teil von '->GetDlgCtrlID' muss auf Klasse/Struktur/Union zeigen Typ ist ''unknown-type''



  • if(ReadFile.Open("C:\\Data.txt", CFile::modeRead)) 
    {
        CEdit* pStartEdit = (CEdit*) GetDlgItem(IDC_EDIT1); //Zeiger auf erste EditBox
        CEdit* pEndEdit=(CEdit*)GetDlgItem(IDC_EDIT2);//Zeiger auf lezte EditBox 
        int startID = pstartEdit->GetDlgCtrlID();  // habe mich vertippt muss pStartEdit heissen 
        int endID   = pendEdit->GetDlgCtrlID(); //und hier pEndEdit!
    
        for (int i = startID; i<= endID; i++) 
        { 
            ReadFile.ReadString(strReadBuffer); 
            CEdit* pEdit = (CEdit*) GetDlgItem(i); 
            pEdit->SetWindowText(strReadBuffer); 
        } 
    
    }
    

    Haben sich 2 Tippfehler eingeschlichen. 😃



  • Kann das Programm jetzt ohne Probleme starten.Danke. Doch wenn ich das Dialogfenster im Menü aufrufen will erhalte ich eine Fehlermeldung und muss das Programm schließen.
    Hier ist die Fehlermeldung

    Debug Assertion Failed
    Program: ...
    File: winocc.cpp
    Line 94

    For information on how your program can cause an assertion
    failure, see the Visual C++ documentation on asserts.



  • Bei der Fehlermeldung kann ich nichts zu sagen.
    Aber setze mal ein paar Breakpoints und debug mal und schaue dir dabei die Werte der Zeiger, etc an.



  • hier ist noch der Code den ich angezeigt bekommen wenn ich bei der Fehlermeldung auf "wiederholen" klicke. Dann wechselt er in den Debug und ziegt mir diesen Code:

    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);
    }
    


  • Scheint wohl, dass dein Programm eine EditBox nicht 'finden' kann.
    Dann aber versucht, einen Text zu setzen.
    Versuch mal:

    ...
    ReadFile.ReadString(strReadBuffer);
    CEdit* pEdit = (CEdit*) GetDlgItem(i); 
    if (pEdit)
        pEdit->SetWindowText(strReadBuffer); 
    ...
    

    Dann überprüft dein Programm vorher, ob der Zeiger gültig ist.



  • Hab den Code geändert doch leider erscheint die Fehlermeldung immer noch.
    Hier ist der Code:

    CDaten::CDaten(CWnd* pParent /*=NULL*/)
    	: CDialog(CDaten::IDD, pParent)
    	, m_sText(_T(""))
    	, m_sText2(_T(""))
    {
    	CString strReadBuffer; 
    
    	CStdioFile ReadFile; 
    	if(ReadFile.Open("C:\\Data.txt", CFile::modeRead)) 
    	{
    		while(ReadFile.ReadString(strReadBuffer)) 
    		{ 
    		CEdit* pStartEdit = (CEdit*) GetDlgItem(IDC_EDIT1); //Zeiger auf erste EditBox 
    		CEdit* pEndEdit=(CEdit*)GetDlgItem(IDC_EDIT2);//Zeiger auf lezte EditBox 
    		int startID = pStartEdit->GetDlgCtrlID(); 
    		int endID   = pEndEdit->GetDlgCtrlID(); 
    
    		for (int i = startID; i<= endID; i++) 
    			{ 
    				ReadFile.ReadString(strReadBuffer);
    				CEdit* pEdit = (CEdit*) GetDlgItem(i); 
    				if (pEdit) 
    				pEdit->SetWindowText(strReadBuffer);
    			}
    
    		} 
    	}
    }
    


  • Kontrolliere mal, ob das dann noch diese Zeilen sind.
    Doppelklick auf Fehlermeldung.
    Sonst zeige mal die aktuellen Fehlermeldungen.



  • Erst mal herzlichen dank, dass du dich so bemühst.
    Die Fehlermeldung ist noch die gleiche und auch die Zeilen sind die selben.

    P.S: Soll ich dir das Programm per e-mail zu schicken, sodass du dir es mal persönlich angucken kannst?(kann auch eine neue e-mail adresse erstellen und da hochladen so erfährt keiner deine e-mail adresse)



  • Du versuchst, im Konstruktor deiner Dialogklasse auf die Steuerlemente zuzugreifen. Die sind aber zu dem Zeitpunkt, wenn der Konstruktor ausgeführt wird, noch gar nicht erstellt. Üblicherweise macht man so etwas in OnInitDialog.


Anmelden zum Antworten