[ Mr. Rejn @ 14.03.2006. 20:35 ] @
Da li neko zna kako se upisuje sadrzaj padajuce liste (ComboBox) u .ini fajl pomocu TIniFile klase? |
[ Mr. Rejn @ 14.03.2006. 20:35 ] @
[ X Files @ 16.03.2006. 16:46 ] @
Tek sad videh pitanje.
Prvo treba da razmislis o mehanizmu za smestanje stavki, tj: a) [neka sekcija] elementi = stavka 1;stavka2;stavka3 ili b) [neka sekcija] element1=stavka 1 element2=stavka 2 element3=stavka 3 ili c) [neka sekcija] br_stavki=3 element1=stavka 1 element2=stavka 2 element3=stavka 3 Evo jedan moj stari (i los) kod, a ceo test projekat ti saljem. Dakle, u njemu vrsim upis i citanje iz INI-ja. Ima cak i GUI za unos stavki. Code: //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include <IniFiles.hpp> #include <StrUtils.hpp> #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { pIni = new TIniFile( ChangeFileExt( ParamStr(0), ".ini" ) ); LastUsedString = pIni->ReadString("Last Used Items", "String", "" ); GoAddStringToListBox( ListBox1, LastUsedString ); ComboBox1->Items->Assign( ListBox1->Items ); if ( ComboBox1->Items->Count > 0 ) ComboBox1->ItemIndex = 0; delete pIni; } __fastcall TForm1::~TForm1() { pIni = new TIniFile( ChangeFileExt( ParamStr(0), ".ini" ) ); LastUsedString = GoGetListBoxToString( ListBox1 ); pIni->WriteString("Last Used Items", "String", LastUsedString ); delete pIni; } void __fastcall TForm1::UpButtonClick(TObject *Sender) { ListBox1->SetFocus(); if ( ListBox1->ItemIndex == -1 ) return; int up = ListBox1->ItemIndex; if ( ListBox1->ItemIndex > 0 ) { ListBox1->Items->Move( ListBox1->ItemIndex, ListBox1->ItemIndex-1 ); --up; } ListBox1->Repaint(); ListBox1->SetFocus(); ListBox1->ItemIndex = up; } void __fastcall TForm1::DownButtonClick(TObject *Sender) { ListBox1->SetFocus(); if ( ListBox1->ItemIndex == -1 ) return; int dw = ListBox1->ItemIndex; if ( ListBox1->ItemIndex < ( ListBox1->Items->Count - 1 ) ) { ListBox1->Items->Move( ListBox1->ItemIndex, ListBox1->ItemIndex+1 ); ++dw; } ListBox1->Repaint(); ListBox1->SetFocus(); ListBox1->ItemIndex = dw; } void __fastcall TForm1::EditButtonClick(TObject *Sender) { ListBox1->SetFocus(); if ( ListBox1->ItemIndex == -1 ) return; AnsiString Text = ListBox1->Items->Strings[ ListBox1->ItemIndex ]; AnsiString Default = Text; bool result = InputQuery( "Edit", "Change the value", Text ); if ( result ) { if ( ( Text == Default ) || ( Text == "" ) || ( strchr( Text.c_str(), ';' ) ) ) return; if ( ListBox1->Items->IndexOf( Text ) != -1 ) return; ListBox1->Items->Strings[ ListBox1->ItemIndex ] = Trim ( Text ); SNDMSG( ListBox1->Handle, WM_VSCROLL, SB_BOTTOM, 0 ); } } void __fastcall TForm1::NewButtonClick(TObject *Sender) { ListBox1->SetFocus(); AnsiString Text = ""; bool result = InputQuery( "New", "Enter new value", Text ); if ( result ) { if ( ( Text == "" ) || ( strchr( Text.c_str(), ';' ) ) ) return; if ( ListBox1->Items->IndexOf( Text ) != -1 ) return; ListBox1->Items->Add( Trim( Text ) ); SNDMSG( ListBox1->Handle, WM_VSCROLL, SB_BOTTOM, 0 ); } if ( ListBox1->Count > 0 ) if ( ListBox1->ItemIndex == -1 ) ListBox1->ItemIndex = 0; } //--------------------------------------------------------------------------- void __fastcall TForm1::DeleteButtonClick(TObject *Sender) { ListBox1->SetFocus(); if ( ListBox1->ItemIndex == -1 ) return; int re = ListBox1->ItemIndex; if ( MessageDlg( "Delete\n" + ListBox1->Items->Strings[ ListBox1->ItemIndex ] + " ?", mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0 ) == mbYes ) { ListBox1->Items->Delete( ListBox1->ItemIndex ); } ListBox1->Repaint(); ListBox1->SetFocus(); if ( re > ListBox1->Items->Count - 1 ) { ListBox1->ItemIndex = --re; } else { ListBox1->ItemIndex = re; } if ( ListBox1->Count > 0 ) if ( ListBox1->ItemIndex == -1 ) ListBox1->ItemIndex = 0; } AnsiString TForm1::GoGetListBoxToString( TListBox *LB ) { AnsiString OT; for ( int i = 1; i <= LB->Items->Count; i++ ) OT += LB->Items->Strings[ i-1 ] + ";"; // Eliminate last ';' OT.SetLength( OT.Length() - 1 ); return( OT ); } void TForm1::GoAddStringToListBox( TListBox *LB, AnsiString STRING ) { STRING = STRING + ";"; int length = STRING.Length(); LB->Clear(); if ( length != 1 ) { char *niz = new char[ length+1 ]; char *pom = new char[ length+1 ]; strcpy( niz, STRING.c_str() ); int prev = 0; for ( int i=0; i<length; i++ ) { if ( niz[i] == ';' || i == length-1 ) { strncpy( pom, &niz[prev], i-prev ); pom[i-prev] = '\0'; LB->Items->Add( Trim( AnsiString( pom ) ) ); prev = i+1; } } delete [] pom; delete [] niz; } if ( LB->Count > 0 ) if ( LB->ItemIndex == -1 ) LB->ItemIndex = 0; } void __fastcall TForm1::UpdateButtonClick(TObject *Sender) { ComboBox1->Items->Assign( ListBox1->Items ); if ( ComboBox1->Items->Count > 0 ) ComboBox1->ItemIndex = 0; } [Ovu poruku je menjao X Files dana 16.03.2006. u 19:10 GMT+1] [ Mr. Rejn @ 17.03.2006. 15:34 ] @
Hvala ti na projektu.. u medjuvremenu sam napravio neki prostiji primer
bez upotrebe TIniFile - stavke se dodaju u ComboBox i istovremeno upisuju u nekakav tekst fajl (npr. combo.log) pritiskom na Enter, a po pokretanju programa lista stavki se ucitava iz loga u Combo iz konstruktora forme. Moze nekome da posluzi ako hoce da izbegne TIniFile ili mu treba sasvim jednostavno belezenje stavki padajuce liste. Code: #include <fstream>; using namespace std; //ucitaj stavke liste iz loga __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { char p[100]; fstream inout("combo.log"); //premotaj na pocetak fajla: inout.seekg(0); // uzmi prvu liniju: while (inout.getline(p,100)) { //dodaj u Combo: ComboBox1->Items->Append(p); } } //unesi stavku padajuce liste u log void __fastcall TForm1::ComboBox1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if (Key == VK_RETURN) { ComboBox1->Items->Append(ComboBox1->Text); //otvori u modu za dopisivanje ofstream str("combo.log",ios::app); str <<ComboBox1->Text.c_str()<<endl; ComboBox1->Text=""; } } [ X Files @ 17.03.2006. 17:12 ] @
Pazi, ako hoces da te stavke drzis u nekom 'neobaveznom' fajlu, i to u nekoj listi jedan
ispod drugoga, onda imas i lakse resenje: Code: // ... ComboBox1->Items->LoadFromFile( NAZIV_FAJLA ) // ... ComboBox1->Items->SaveToFile( NAZIV_FAJLA ) // ... Taj 'Items' pokazivac je tipa TStringList, a on vec ima sve sto ti treba za snimanje/ucitavanje. Inace, savetujem ti da uvek fajlovima obezbedjujes *pune putanje* Dakle, umesto: Code: ComboBox1->Items->SaveToFile( "fajl.dat" ) bolje je: Code: ComboBox1->Items->SaveToFile( ExtractFilePath( ParamStr( 0 ) ) + "fajl.dat" ) // ili: ComboBox1->Items->SaveToFile( ExtractFilePath( Application->ExeName ) + "fajl.dat" ) ...ako je fajl u putanji exe-a. Zbog cega je bolje? Prosto, u Win programiranju lako moze da se 'pobegne' iz putanje EXE fajla i to nenamerno i da vise ono sto je nekada radilo vise ne radi. Kod Borland C++ Buildera, koliko se secam, dovoljno je da imas neki obican dijalog tipa TOpenDialog/ TSaveDialog, i nakon izbora neke lokacije za snimanje/ucitavanje - vise nisi u root-u, tj, kao da si odradio rucno SetCurrentDir( negde drugde ). [ Mr. Rejn @ 18.03.2006. 10:46 ] @
Citat: Code: // ... ComboBox1->Items->LoadFromFile( NAZIV_FAJLA ) // ... ComboBox1->Items->SaveToFile( NAZIV_FAJLA ) // ... Da.. ![]() Eto totalno sam prevideo tu metodu. [ X Files @ 18.03.2006. 11:06 ] @
U tome i jeste lepota i kvalitet VCL-a - sto je sve logicno i u duhu OOP-a.
Gde god se pominje neki NATPIS, on je tipa AnsiString, a gde god se pominje nekakva lista to je uglavnom TStringList. [ Mr. Rejn @ 18.03.2006. 11:46 ] @
Zamisli ovakvu situaciju: upisujes nesto u Combo sto mora da ostane
tamo i upisujes listu stavki u fajl tek kada izadjes iz programa po- mocu SaveToFile i ... nestane struja pre nego sto zavrsis! Onda se gube sve stavke u listi! Mozda je bezbednije odmah upisivati u fajl preko stream-a. Doduse moze se i tu koristiti SaveToFile: Code: ... if (Key == VK_RETURN) { ComboBox1->Items->Append(ComboBox1->Text); ComboBox1->Items->SaveToFile("combo.log"); ComboBox1->Text=""; } [Ovu poruku je menjao Mr. Rejn dana 18.03.2006. u 13:10 GMT+1] [ X Files @ 18.03.2006. 12:10 ] @
Ja mislim da je skoro isto i stream-ovanje i SaveToFile()
Cak i da imas 100,000 stavki upis ce ti trajati DELIĆ sekunde. Ako ti je bitno da to SIGURNO bude snimljeno, onda mozes da pronadjes neki dogadjaj koji ce snimiti u fajl izmene odmah nakon promene u Combo-u. [ Mr. Rejn @ 18.03.2006. 12:20 ] @
Hehe, ja sam promenio poruku,a ti si poslao poruku u istom trenutku..
Da, verovatno je razlika u brzini upisa u fajl za stream/SaveToFile zanemarljiva sto se tice neke prakticne upotrebe. Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|