x-kom hosting

Problem z C++ Builder 6

leggo
komentarz
komentarz

Mimo dopisania dodatkowych znaków zaznaczony pozostaje poprzednio wyszukany element, ponieważ nie czyścisz zaznaczenia, w momencie nieznalezienia żadnych pasujących elementów. Wywołując funkcję [b]Perform[/b] powinieneś pobrać wartość przez nią zwracaną (liczba całkowita). Jeżeli funkcja nie znajdzie na liście żadnego pasującego string-a zwróci wartość [b]LB_ERR[/b]. Gdy tak się stanie, powinieneś czyścić zaznaczenie (wtedy też pokazujesz komunikat "Nic nie znaleziono").

 

 

MS mówi, żeby nie używać [b]LB_SELECTSTRING[/b] na ListBox-ach z MultiSelect. Zamiast tego możesz użyć [b]LB_FINDSTRING[/b]. Ten komunikat jako parametr zwracany odda Ci indeks znalezionego string-a (zaznaczyć musisz sam) lub [b]LB_ERR[/b] w przypadku nie znalezienia żadnego pasującego elementu.

Żeby w ten sposób znaleźć więcej pasujących elementów listy wywołujesz metodę [b]Perform[/b] kilka razy na początku jako [b]wParam[/b] podajesz -1, a przy następnych wywołaniach ostatnio zwrócony indeks (zaczynasz wyszukiwanie od elementu znajdującego się pod ostatnio znalezionym). Wywołujesz tą funkcję tak długo, aż zwróci [b]LB_ERR[/b] lub indeks znaleziony przy pierwszym wywołaniu (to znaczy, że zaczął przeszukiwać od początku).

  • Dobra wypowiedź 1

Kremius
komentarz
komentarz (edytowane)

Troszkę to zagmatwane, możesz podać jakiś przykład?

 

 

Edit 1

Zamiast LB_SELECTSTRING wpisałem LB_FINDSTRING , oraz LPARAM na WPARAM (nie zmieniając nic więcej) i wyszukiwanie przestało mi działać.

Edytowane przez Kremius
leggo
komentarz
komentarz (edytowane)

Tak np. może wyglądać wyszukiwanie, w którym będzie odznaczany poprzednio wyszukany wyraz (to odnośnie postu #46):

if(!Edit1->Text.IsEmpty())
        if(LB_ERR == ListBox1->Perform(LB_SELECTSTRING, -1,(LPARAM)Edit1->Text.c_str()))
                ListBox1->ItemIndex = -1;

 

Wyszukiwanie za pomocą findstring:

indeks = ListBox1->Perform(LB_FINDSTRING, -1,(LPARAM)Edit1->Text.c_str());  //w zmiennej indeks znajduje się indeks pierwszego pasującego wyrazu

indeks = ListBox1->Perform(LB_FINDSTRING, indeks,(LPARAM)Edit1->Text.c_str());  //w zmiennej indeks znajduje się indeks kolejnego pasującego wyrazu

LB_FINDSTRING również zwraca LB_ERR gdy nic nie znajdzie.

Oczywiście w przypadku findstring też musisz sprawdzić czy Edit1 nie jest pusty.

Edytowane przez leggo
Kremius
komentarz
komentarz

Dzięki wyszukiwanie działa poprawnie. Tylko mam takie pytanie jak usunę wszystko z pola Edit1 to cały czas jest zaznaczone ostatnie wyszukanie. Można to zmienić, tak aby pola ListBox1, ListBox2 były pokazane od początku, tylko bez zaznaczenia - czyli tak jak po skompilowaniu programu?

leggo
komentarz
komentarz
if(!Edit1->Text.IsEmpty())
{
        if(LB_ERR == ListBox1->Perform(LB_SELECTSTRING, -1,(LPARAM)Edit1->Text.c_str()))
        {
                ListBox1->ItemIndex = -1;
                ListBox1->TopIndex = 0;
        }
}
else
{
        ListBox1->ItemIndex = -1;
        ListBox1->TopIndex = 0;
}
Kremius
komentarz
komentarz

Jeszcze jedno. Czy można tą metodą sprawdzić ostatni znak ciągu znaków i zastąpić go innym. Pamiętam, że o coś takiego chyba pytałem, lecz chodzi mi teraz o C++ Builder i nie wiem czy tamto zadziała i jak to wyglądało.

leggo
komentarz
komentarz

[quote name='Kremius' timestamp='1360500763' post='1698969'] Czy można tą metodą sprawdzić ostatni [/quote]

Którą metodą?

 

Ostatni znak ciągu:

Edit1->Text[Edit1->Text.Length()]
Kremius
komentarz
komentarz

Nie pamiętam jakie są. Poza tym takie pytanie na szybko czy jest jakiś komponent, lub też sposób, aby wyświetlić stronę WWW w C++. Nie chodzi mi o otworzenie przeglądarki lecz stronę napisaną w HTML'u, która była by wyświetlana na Form1?

leggo
komentarz
komentarz

Komponent CppWebBrowser.

Kremius
komentarz
komentarz

Może to i śmieszne, ale nie mogę go znaleźć w żadnej zakładce...

leggo
komentarz
komentarz

Component -> Import ActiveX Control... -> Microsoft Internet Controls -> Install

  • 1 miesiąc później...
Kremius
komentarz
komentarz

Słuchaj! Mam jeszcze takie pytanie. Czy można zrobić coś w rodzaju dynamicznego usuwanie plików. Tzn. plik zostanie usunięty tylko w tedy jeśli w komponencie ComboBox nie znajdzie się jego nazwa (jedna z linijek nie będzie miała takiej samej nazwy - wówczas program usunie pliki)?

 

Z góry dzięki za odpowiedź

leggo
komentarz
komentarz

Jak przeszukać combobox już wiesz.

 

Plik z dysku możesz usunąć funkcją [b]remove[/b]. Jeśli funkcja zwróci zero, to znaczy, że plik został usunięty poprawnie.

remove("adres pliku");

 

Oczywiście nie muszę chyba nadmieniać, że przy zabawach z usuwaniem plików trzeba być ostrożnym.

  • 2 tygodnie później...
Kremius
komentarz
komentarz

Mam takie pytanie odnoście innego programu który chcę zrobić. Otóż, czy jest możliwość przeliczenia wyniku obliczeń na czas. Tzn jeśli wyjdzie mi wynik 3600 program pokaże 1h, albo przy wyniku 3900 1h 5min. Oraz czy można wyniki zaokrąglać w dół, górę do liczby całkowitej (tak samo jak odpowiednie funkcje w Excelu)...

leggo
komentarz
komentarz

Teoretycznie mógłbyś użyć biblioteki do obsługi czasu (time.h), ale w gruncie rzeczy przysporzy Ci to tylko dodatkowych problemów. Prościej będzie jak sobie to sam przeliczysz (dzieląc przez 60). Do zaokrąglania liczb w wybranym kierunku służą funkcje z biblioteki math.h: [b]ceil[/b] (w górę) i [b]floor[/b] (w dół).

Kremius
komentarz
komentarz

OK, dzięki. Jeśli chodzi o obsługę ini. Jak zrobić, aby można było zapisać dane z pól edit1, edit2 itp do pliku ini, następnie zamknąć program otworzyć go jeszcze raz i po wybraniu odpowiedniej opcji z combobox'a wczytać wcześniej zapisane dane. oraz jak zrobić aby 'sekcja' w pliku ini była dynamiczna, tzn aby przy tworzeniu nowej sekcji (na końcu pliku ini) wpisać samodzielnie jej nazwę. Ostatnie pytanie odnośnie dynamicznego tworzenia listy combobox'a, po wciśnięciu w odpowiednią opcję aby wyświetlało dane tylko te, które znajdują się w sekcji o takiej samej nazwie jak opcja.

 

Gdybyś mógł pomóc mi to rozwiązać byłbym niezmiernie wdzięczny, gdyż bardzo tego potrzebuje...

leggo
komentarz
komentarz

Na początek musisz dołączyć sobie dodatkowy nagłówek (w pliku [b]Unit1.h[/b]):

#include <inifiles.hpp>

Następnie tworzysz wskaźnik na odpowiedni plik (jeśli podany plik nie istniej zostanie utworzony przy pierwszej operacji zapisu do tego pliku):

TIniFile* plik = new TIniFile("nazwaPliku.ini");

Przy pomocy utworzonego wskaźnika możesz zapisywać i odczytywać dane:

plik->WriteString("nazwa sekcji", "nazwa parametru", "wartosc");   //zapis
AnsiString tekst = plik->ReadString("nazwa sekcji", "nazwa parametru", "domyslna wartosc");   //odczyt

Oczywiście każdy z parametrów tych funkcji możesz zastąpić zmiennymi (to odnośnie dynamicznych sekcji ;) )

 

Wpisanie wszystkich parametrów i wartości z podanej sekcji do ComboBox-a:

plik->ReadSectionValues("nazwa sekcji", ComboBox1->Items);
Kremius
komentarz
komentarz

zrobiłem tak:

1. Otworzyłem Unit1.h i dodałem #include <inifiles.hpp>

2. Skopiowałem TIniFile* plik = new TIniFile("nazwaPliku.ini"); do funkcji Button1Click

3. Następnie linijkę z zapisem do pliku, tylko zamiast "wartosc" dałem Edit1->Text

4. skompilowałem to wpisałem coś w pole Edit1  i nic, pliku mi się nie pokazał

 

Pytanie moje dlaczego. Dodam, że przy kompilacji nie było żadnych błędów, czy czegoś tego typu.

leggo
komentarz
komentarz

Powinno działać.

Upewnij się, że szukasz pliku w dobrym miejscu. Najlepiej dla testów podaj tam adres bezwzględny do miejsca, w którym nie będzie problemu z uprawnieniami do zapisu (np. d:\\nazwaPliku.ini).

Kremius
komentarz
komentarz (edytowane)

dzięki wszytko działa (z adresem bezwzględnym), ale dlaczego mi nie działało bez podania całej ścieżki? jeszcze jedno napisałeś jak wczytać wartości z podanej sekcji do ComboBox można zrobić coś podobnego tylko, że zamiast wartości będzie wpisywało wszystkie sekcje jakie są w pliku ini?

Edytowane przez Kremius
leggo
komentarz
komentarz
plik->ReadSections(ComboBox1->Items);
Kremius
komentarz
komentarz

Dzięki wszytko działa, tylko nadal mam 2 błędy:

1. w zasadzie nie błąd, ale jak zrobić, abym nie musiał podawać ścieżki bezwględej

2. wpisałem coś takiego:

ComboBox1->DeleteSelected();
plik->EraseSection(ComboBox1->Text);

Ogólnie ma ta funkcja kasować sekcję wraz z jej parametrami, której nazwę (sekcji) będzie brać brać z pola ComboBox z wartości Text. Moje pytanie, gdzie popełniłem błąd, gdyż wyskakuje mi błąd.

leggo
komentarz
komentarz

W taki sposób możesz zapisywać pod względnym adresem:

AnsiString sciezka = ExtractFilePath(Application->ExeName);
plik = new TIniFile(sciezka + "nazwaPliku.ini");

Czy treść pojawiającego się błędu nie dała Ci do myślenia? Podany przez Ciebie fragment wyrzuca błąd ponieważ najpierw usuwasz obiekt z combobox-a, a później (gdy obiekt już nie istnieje) posługujesz się nim do wskazania sekcji. Zamień te dwie linijki miejscami (najpierw usuwaj z pliku, a dopiero później z combo), a będzie działać poprawnie.

  • Dobra wypowiedź 1
Kremius
komentarz
komentarz

dzięki wszystko działa jak powinno, ścieżki oraz usuwanie sekcji

 

wielkie dzięki

Kremius
komentarz
komentarz (edytowane)

Ogólnie robię komunikator internetowy (client-server w jednym), wszystko działa lecz mam problem z kilkoma rzeczami:

1. Nie wiem jak zrobić listę użytkowników, tzn W funkcji ServerSocket1ClientConnect mam coś takiego:

AnsiString klient=Socket->ReceiveText();
ListBox1->Items->Add(klient);
Memo1->Lines->Add("Podlaczono klienta: "+klient+" "+Socket->RemoteAddress+" "+Socket->RemoteHost);

zmienna klient, to nazwa użytkownika, którą client wysyła przy połączeniu się do serwera, która następnie ma być wyświetlona w komponencie ListBox1

 

2. Nie wiem jak dodać listę użytkowników do clienta, gdyż jak otworzę program i dam tryb serwera i ktoś się podłączy (na razie ta sama aplikacja działająca w trybie client) to lista użytkowników jest tylko na serwerze, a chcę dodać ją także do clienta. (lista wyświetla się tylko w postaci adresów IP, a nie nazw, które client wysyła przy podłączeniu się do serwera)

 

3. Jak zrobić wysyłanie do określonego użytkownika, zależy mi aby wykorzystać przy tym komponent TabbedNotebook1, oraz żeby wyglądało to mniej więcej tak na początku jest tylko zakładka (w tym komponencie) Globalne, następnie po podłączeniu się do serwera innego użytkownika, aby jego nazwa była dodana do ListBox1, oraz po kliknięciu w wybraną nazwę (w komponencie ListBox1) utworzyła się nowa zakładka w TabbedNotebook1 podpisana nazwą wybranego użytkownika; po odłączeniu się użytkownika nazwa była usuwana z ListBox1 oraz zakładka użytkownika w TabbedNotebook1 była kasowana.

 

Z góry dzięki za jakąkolwiek pomoc.

 

 

Edit1

Rozwiązałem problem listy użytkowników, lecz nadal nie widać jej gdy podłącze się jako client, wiesz może jak to rozwiącać?

Poza tym wpadłem na szybszy sposób wysyłania wiadomości do konkretnej osoby, czy można zrobić coś takiego, że w polu Edit2 wpiszę login tej osoby, program sprawdzi, czy taka osoba jest podłączona i wyślę tylko do tej osoby? Np. po podłączaniu będą dodawać się do tablicy (dynamicznej, oczywiście po odłączeniu będą usuwani), kiedy wpisze np user12 program sprawdzi czy taki jest podłączony, jeśli tak to wyślę mu wiadomość z pola Edit1

 

Z góry dzięki za szybką pomoc...potrzebuje tego po długim weekendzie...

Edytowane przez Kremius

Wciąż szukasz rozwiązania problemu? Napisz teraz na forum!

Możesz zadać pytanie bez konieczności rejestracji - wystarczy, że wypełnisz formularz.

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Strona wykorzystuje pliki cookies w celu prawidłowego świadczenia usług i wygody użytkowników. Warunki przechowywania i dostępu do plików cookies możesz zmienić w ustawieniach przeglądarki.