InsertString CComboBox Problem
-
Hallo, ich versuche den CComboBox und seine verschiedenen Funktionen zu verstehen. Dafür habe ich ein kleiner Dialog Based Programm angebaut. Das Programm hat einen combobox. Ich will dem Benutzer die Möglichkeit geben, einen neuen Eintrag (m_ColorName) zur Liste (m_ColorList) hinzuzufügen.
Ich habe zwei Check Controls (Alte und Neue Farben), ein combobox (um die Farbe der Liste auszuwählen, wenn Alte Farbe ausgewählt wird) und zwei Edit Controls (um eine neue Farbenzahl hinzuzufügen, wenn Neue Farbe ausgewählt wird) eingebaut.
Ich habe die folgenden Variablen deklarieren:
DDX_Control(pDX, IDC_COMBO1, m_ColorList); DDX_Text(pDX, IDC_IDCOLOR, m_IdColor); DDX_Text(pDX, IDC_COLORNAME, m_ColorName); DDX_Check(pDX, IDC_NEWCOLOR, m_NewColor); DDX_Check(pDX, IDC_OLDCOLOR, m_OldColor);
Ich will eine Zahl automatisch für die neue Farbe geben, dafür verwende ich die GetCount-Funktion, und ich initialisiere im OnInitDialog. Diese Zahl (m_IdColor) muss die Gesamtzahl der Eintrag (nNoOfEntries) in der ComboBox (m_ColorList) plus eins sein. Es funktioniert gut am Anfang wenn ich offne die erstes Mal das Programm.
Der Benutzer kann nur eine neue Farbe zum ColorList hinzufügen, wenn er die NewColor Check Control auswählt. Diese neue Farbe (m_ColorName) kann nur zur Liste hinzugefügt, wenn der Benutzer klickt auf Save. Es funktioniert gut, die neue Farbe wird zur Liste hinzugefügt, aber die Farbenzahl (m_IdColor) wird nicht aktualisiert.
Ich will auch, dass diese neue Farbe ist für das nächste Mal abgespeichert, wenn ich das Programm neu öffne. Aber es funktioniert nicht.
Der Code, dass ich verwende, ist:
BOOL CMyComboBoxAddingDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. .......... // TODO: Add extra initialization here //The Save button should be activated only if New Material is selected. GetDlgItem(IDSAVE) -> EnableWindow(FALSE); //Definition of variable nNoOfEntries equal to the total number of options in the ColorList int nNoOfEntries = m_ColorList.GetCount(); m_IdColor = nNoOfEntries + 1; // Assignment a number for the new Color UpdateData(FALSE); // would update the data from control variables to control return TRUE; // return TRUE unless you set the focus to a control } void CTubeMaterial::OnSelMaterial() { UpdateData(TRUE); //transfers the index to the variable. m_Material = m_MaterialList.GetCurSel(); UpdateData(FALSE); } void CMyComboBoxAddingDlg::OnOK() { // TODO: Add extra validation here if(m_NewColor) { // Association of a pointer to the EditControl CEdit *pColorName = static_cast<CEdit*>(GetDlgItem(IDC_COLORNAME)); // Checking if there is some text if (pColorName->LineLength() == 0) MessageBox("No entry in the entry field available!"); else { // To read the text pColorName->GetWindowText(m_ColorName); // Inserting to the ComboBox m_ColorList.InsertString(-1,m_ColorName); // Deleting the text //pColorName->SetWindowText(""); } } CDialog::OnOK(); } void CMyComboBoxAddingDlg::OnSave() { // TODO: Add your control notification handler code here if(m_NewColor) { // Association of a pointer to the EditControl CEdit *pColorName = static_cast<CEdit*>(GetDlgItem(IDC_COLORNAME)); // Checking if there is some text if (pColorName->LineLength() == 0) MessageBox("No entry in the Color Name field available!"); else { // To read the text pColorName->GetWindowText(m_ColorName); // Inserting to the ComboBox m_ColorList.InsertString(-1,m_ColorName); // Deleting the text //pColorName->SetWindowText(""); } } }
-
Deine Variable nNoOfEntries wird an keiner stelle des Progarmmes aktualisiert, also wie soll sich der Wert ändern. Wobei die Variable is unnütz, da du dein Ctrl Fragen kannst wie viel Einträge es enthält.
Das nach dem Beenden des Programmes nichts mehr da ist liegt nur daran das du auch die Einträge in deinem Ctrl nicht Speicherst und beim Start auch nicht wieder ein liesst, dazu sind Klassen wie CFile oder CArchiv oder CStdioFile nützlich, diese könne in eine Datei scheiben und daraus lesen. Einstellunger in deinem Programm werden nun mal nicht automatisch gespeichert.
-
wie kann ich die variable nNoOfEntries aktualisieren?
-
na an der stelle wo du einen neuen Eintrag machst oder einen Löschst kannst du die variable genau so wie du sie in der OnInitDialog aktualisierst. Nur ist die Variable Sinnfrei weil du auch gleich m_ColorList.GetCount() nutzen kannst, was dir mit Sicherheit immer das richtige Ergebnis bringt. Deine Variable kann durch einen Fehler falsch sein weil der Wert nicht stimmt weil du an einer stelle vergessen hast die zu setzen.
-
Ich verstehe nicht ganz wieso die Variable nNoOfEntries Sinnfrei ist. Meinst du dass
int nNoOfEntries = m_ColorList.GetCount();
m_IdColor = nNoOfEntries + 1;ist is die gleiche als
m_IdColor = m_ColorList.GetCount() + 1;
-
Ich habe unter die Funktion OnSave die möglichkeit die neue Eintrage zu speichern implementiert und es funktioniert gut. Aber ich habe probleme um das Datei zu öffnen und lesen. Die habe ich implementiert in die OnInitDialog implementiert und deshalb vielleicht es funktioniert nicht richtig. Hier ist die Code:
BOOL CMyFileDlg::OnInitDialog() { CDialog::OnInitDialog(); .............. // TODO: Add extra initialization here //------------------------------------------------------------- // Opening the file color.dat to be able to actualize CComboBox //------------------------------------------------------------- CStdioFile file; file.Open("color.dat", CFile::modeRead | CFile::typeBinary); if(file) { file.ReadString(m_ColorName); file.Close(); } //------------------------------------------------------------- // Adding the new ColorName to the CComboBox //------------------------------------------------------------- if(m_ColorName) { m_ColorList.InsertString(-1,m_ColorName); } //------------------------------------------------------------- //The Save button should be activated only if New Material is selected. //------------------------------------------------------------- GetDlgItem(IDSAVE) -> EnableWindow(FALSE); //------------------------------------------------------------- //Assigment of a number for new Colors //------------------------------------------------------------- //Definition of variable nNoOfEntries equal to the total number of options in the ColorList int nNoOfEntries = m_ColorList.GetCount(); m_IdColor = nNoOfEntries + 1; // Assignment a number for the new Color UpdateData(FALSE); // would update the data from control variables to control return TRUE; // return TRUE unless you set the focus to a control } void CMyComboBoxAddingDlg::OnSave() { // TODO: Add your control notification handler code here if(m_NewColor) { //------------------------------------------------------- // Obtaining new color name and adding to the combobox //------------------------------------------------------- // Definition of a pointer pMaterialName of the type CEdit & // Obtaining the value in the Edit Control CEdit *pColorName = static_cast<CEdit*>(GetDlgItem(IDC_COLORNAME)); //CEdit* pName = (CEdit*)GetDlgItem(IDC_COLORNAME); // Checking if the EditControl is not empty if (pColorName->LineLength() == 0) //if empty MessageBox("Please insert a Material Name!"); else // if not empty { // Obtain the Text in m_ColorName pColorName->GetWindowText(m_ColorName); // & adding to the ComboBox List in the last position m_ColorList.InsertString(-1,m_ColorName); } //------------------------------------------------------- // Writing the New Colors on the file color.dat //------------------------------------------------------- //Creating a storing archive of type CFile / CStdioFile: file CStdioFile file; //Opening the file file.Open("color.dat", CFile::modeCreate | CFile::modeNoTruncate | CFile::modeReadWrite | CFile::typeBinary); file.SeekToEnd(); // Moving the cursor to the End of the file. UpdateData(TRUE); // transferring the content of the edit boxes to the variables //Writing the context of each variable file.WriteString(m_ColorName); file.WriteString("\n \n"); //Closing the file file.Close(); UpdateData(FALSE); AfxMessageBox("Data is saved"); } }
Ich kriege eine Assertion bei ReadString. Ich weisse nicht wo den Fehler kann sein. Kann mich jemand helfen?
-
ich würde jetzt mal Behaupten das dein File nicht geöffnet werden kann, das kannst du natürlich nicht mitbekommen, da du bei der if ja nur Testtest ob das Objekt da ist
CStdioFile file; file.Open("color.dat", CFile::modeRead | CFile::typeBinary); if(file) //hier ist dein Problem
wenn musst du schon die Rückgabe von Open auswerten. Ist die TRUE dann ist alles OK, ist diese FALSE solltest du im else-Zweig mit GetLastError() rausfinden wo das Problem liegt.
Zu deiner Variable nNoOfEntries, da ich diese nur in OnInitDialog seh wo diese gesetzt wird und an sonsten keine weitere Verwenung, sehe ich diese als Sinnfrei an, vor allem bei dem Hintergrund das du m_ColorList.GetCount() benutzen kannst um den Wert zu ermitteln, nNoOfEntries kann inkosistent werden was wiederum dann zu Problemen führen kann. Das gleiche mit der Variable m_IdColor welche immer den Wert m_ColorList.GetCount()+1 hat, also genau so Sinnfrei ist
-
Um den Fehler bei einem Open zu ermitteln ist es besser ein Exception Object beim Open als weiteren Parameter (3.) anzugeben.
-
Vielen Dank für eure Hilfe. Ich habe es gefunde wieso bekomme ich den Fehler, aber ich habe es versucht zu korrigieren aber leider alle meine versuchen funktionieren nicht.
Ich will nur den Datei offnen wenn diese Datei existiert, wenn nicht existiert dann nicht. Das Fehler bekomme ich weil die Datei wird immer geoffnet egal ob existiert oder nicht. Können Sie mich helfen?
Mein versucht war:
if(file) { while(file.ReadString(m_ColorName)); { if(!m_ColorName.IsEmpty()) // if the variable is not empty { } else // if empty file.Close(); } }
-
if (file)
Kann nicht funktionieren. Das wurde doch schon geschrieben.
Verwende:if (file.Open(...))
-
Vielen Dank für deine Hilfe. Endlich kriege ich keine Assertion wenn die Datei nicht existiert. Leider jetzt kriege ich eine Assertion in file.ReadString(line).
Die Datei sieht wie folgenden aus:
7 orange
8 gelbIch benutze file.ReadString(line); (http://msdn.microsoft.com/es-es/library/x5t0zfyf(v=vs.80).aspx) um die ganze Zeile zu lesen, aber es funktioniert nicht. Das Problem glaube liegt genau in ReadString(line), was mache ich falsch?
CStdioFile file; CString FilePath; // Variable FilePath to obtain the path of the file color.dat CString line; // Variable line to read each line of the file color.dat CString TextLine = " "; // Variable to assign the contexts of the buffer variable const int nMax = 100; // Variable nMax equal to 100 char buffer[nMax]; // Array with nMax-1 characters to store temporary the data reads from the file FilePath = "C:\\color.dat"; // Obtaining the path of color.dat TextLine = buffer; if(!file.Open(FilePath, CFile::modeRead | CFile::typeBinary)) { while(line.IsEmpty()) { file.ReadString(buffer, 99); sscanf(buffer,"l4d%20s",&m_IdColor, &m_ColorName); } file.Close(); }
Ich habe
line.Format("%3d", m_IdMaterial); file.WriteString(line); line.Format("%1s", " "); file.WriteString(line); line.Format("%-20s\n", m_MaterialName); file.WriteString(line);
benutzt um auf den Datei zu schreiben ? Gibt es etwas Äquivalent zum lesen?
-
Ich habe endlich den Fehler gelöst.
Der endgültige Code ist:
if(file.Open("color.dat", CFile::modeRead)) { while(line.IsEmpty()) { file.ReadString(line); //To assign the values of line to m_IdColor, m_ColorName, ... } file.Close(); } else { CString ErrorMsg; CFileException fileException; ErrorMsg.Format("Can´t open file %s, error: %u", "color.dat", fileException.m_cause); AfxMessageBox(ErrorMsg); }
Jetzt fehlt nur die gelesen Werten in jeder Variable zuzuweisen und die CComboBox zu aktualisieren.
-
laephy schrieb:
Ich habe endlich den Fehler gelöst.
Der endgültige Code ist:
if(file.Open("color.dat", CFile::modeRead)) { while(line.IsEmpty()) { file.ReadString(line); //To assign the values of line to m_IdColor, m_ColorName, ... } file.Close(); } else { CString ErrorMsg; CFileException fileException; ErrorMsg.Format("Can´t open file %s, error: %u", "color.dat", fileException.m_cause); AfxMessageBox(ErrorMsg); }
Jetzt fehlt nur die gelesen Werten in jeder Variable zuzuweisen und die CComboBox zu aktualisieren.
Das ist so natürlich Unfug. CFileException fileException; muss vor dem Open definiert werden und ein Zeiger auf die Excpetion muss an die Funktion übergeben werden, wenn Du den Fehler behandeln willst.