Pobieranie danych z pola Edit i jego ukrywanie

0

Witam,
mam kłopot: pobieram dane z pola Edit w ten sposób:

AnsiString c_str=Edit1->Text

Ponieważ Edit staje się Visible podczas Clicka na Image, chciałbym zrobić dwie rzeczy:

  1. w momencie wpisania do Edit znaku i/lub po nacisnięciu Enter pole Edit ma byc Visble=false
  2. tekst z pola Edit, juz jako c_str ma zostać użyty w funkcji Clicka, czyli wyglądałoby to tak, jakbyśmy wychodzili z funkcji OnClick w Image, wchodzili do Edit, tam wpisywali, pobierali ten tekst z powrotem do OnClicka.... jest takie "zawieszenie" funkcji mozliwe? (w zależności od wpisanego tekstu ma pobrać do Image'a funkcja switch inny Picture)

To mój pierwszy projekt w C++Builderze. Poproszę o ew. podpowiedź, inne rozwiązanie jeśli moje jest z góry uznane za niemożliwe:)

0

hehe... śmieszne, ale prawdziwe... możliwe, że dlatego, że poświęciłem już jakis kawałek swojej pracy nad tym projektem, to za wszelką cenę chcę uparcie brnąć w tym kierunku.. szkoda mi tego co zrobiłem.
w każdym razie brak mi wiedzy na temat możliwości wykorzystania właściwości i eventów obiektów w Builderze... Poproszę Was o nazwę książki z celnymi, prosto wytłumaczonymi tychże w Builderze. cofnę się, aby nabrać rozpędu...

2

@k1313: myślę, że nikt w tym wątku nie odpowiedział, dlatego że nikt nie zrozumiał tego co chcesz zrobić. Spróbuj więc jeszcze raz wytłumaczyć o co chodzi w tych dwóch punktach. ;)

Jeśli o lekturę chodzi, to dokumentacja dostarczona wraz ze środowiskiem w zupełności wystarczy (ew. skorzystaj z tej dostępnej w sieci). Znajdziesz tam wszystkie potrzebne informacje na temat systemu zdarzeń.

0

To ja może dopowiem odnośnie książek. Jak tak @furious programming napisał. Najważniejsza jest dokumentacja. W moim doznaniu jest ona dobrze zrobiona, łatwo się w niej połapać. Jednak jeśli szukasz jakichś książek to niestety muszę Cię zmartwić. Odnośnie C++ Builder'a dawno nie wyszła żadna nowa sensowna książka. Są co prawda jakieś starocie opisujące programowanie w C++ Builderze 6 czy nawet 5 (nie pamiętam tytułów, ale są nawet przekłady w naszym języku 5-tka w wersji dwutomowej 6-tka w jednym od Heliona). Do wprowadzenia i poznania filozofii można by przeczytać. Jednak reszta to studiowanie dokumentacji.

0

ok, spróbuję jeszcze raz, poprzedni post pisany był w momencie całkowitej pomroczności jasnej, podczas prób kodowania... ciężko wtedy mysleć jak człowiek, eech..

  1. program ma pozwalać użytkownikowi nadać wartość liczbową (i wyświetlić ją) komórki pól Sudoku (81)
  2. tak sobie umyśliłem, znalawszy piękną grafikę (!sic! kajam się...), że komórkami tymi będą Pola Image do których będę wczytywał odpowiedni Picture, w zależności od tego co wpisze użytkownik w pkt 1 (od 1-9)
  3. OnClick Image ma powodować, że:
    3a. pojawia się Pole Edit (zmiana Visible),
    3b. tam wpisujesz cyferkę i
    3c. po naciśnięciu Enter (PressKey) wczyta cyfrę z Edita, wybierze do wczytania Picture do Image oraz aktualizuje tablica 3D całego Sudoku.
    taki był/jest plan

teraz wytłumaczę, co potrzebuję:

  • OnClick Image'a startuje funkcję. Ta, w pierwszej linii pokazuje Pole Edit, wtedy użytkownik przechodzi do Edit, żeby wpisać cyfrę... A tymczasem w kolejnej linii funkcji OnClicka już chcę użyć tekstu z Edit, by wybrać obrazek.

A przecież nie da rady dwutorowo działać! ..muszę więc wybór obrazka umieścić w innym evencie. np. PressKey Edita... Ale Edit ma służyc wielu komórkom, więc musi zwracać tę wartość z powrotem do Pola, które go wywołało...JAK? (przepraszam za przydługi tekst, ale w trakcie pisania, parę rzeczy mi się wyjaśniało i w międzyczasie poprawiałem w programie)
Więc jak? Jak wrócić z powrotem do funkcji, która "otworzy" nam Edita, który po zmianie tekstu otrzyma chara/stringa..?

Edyta łąja mnie, mówiąc, żebym najpierw napisał program, który działa, a potem go sobie kwiatkował grafiką. No tak, ale tak czy siak, jak wrócić do funkcji z wartością?

1

Teraz przynajmniej wiadomo dokładnie o co chodzi. ;)

Z tego co widzę, całość można zamknąć dwoma zdarzeniami. Pierwsze to OnClick po kliknięciu w kontrolkę obrazka. W tym zdarzeniu pobierz współrzędne tej kontrolki, wyczyść zawartość pola edycyjnego i wyświetl je w odpowiednim miejscu w oknie. Dodatkowo, zapamiętaj np. w dodatkowym polu klasy okna klikniętą kontrolkę, a dokładniej jej referencję. To będzie potrzebne w dalszej części.

Drugim zdarzeniem może być OnKeyPress. W nim sprawdź czy wciśnięto Enter oraz czy pole edycyjne zawiera poprawną liczbę. Jeśli tak, to ukryj pole edycyjne, na podstawie podanej liczby określ ścieżkę obrazka i za pomocą zapamiętanej w dodatkowym polu referencji, załaduj ten obrazek do kontrolki.

0

Jeeezu... jeszcze nie wszystko wiem jak zrobić z tego co powiedziałeś.:))) lecę na googla...

pobierz współrzędne tej kontrolki(...) zapamiętaj np. w dodatkowym polu klasy okna klikniętą kontrolkę, a dokładniej jej referencję. >

mam pobrać Left i Top? tak: int x=P1->left , int y=P1->Top ???

OnKeyPress. W nim sprawdź czy wciśnięto Enter (...) Jeśli tak, to ukryj pole edycyjne,

if (getchar()=='\n') Edit1->Visible=false; ?

za pomocą zapamiętanej w dodatkowym polu referencji, załaduj ten obrazek do kontrolki.

.....?

1
k1313 napisał(a):

mam pobrać Left i Top? tak: int x=P1->left , int y=P1->Top ???

Sądziłem, że to już masz. No ale tak, dokładnie o to chodzi. Wskaźnik na instancję klikniętej kontrolki dostajesz w parametrze Sender tego zdarzenia, więc użyj go do odczytania pozycji.

if (getchar()=='\n') Edit1->Visible=false; ?

getchar używa się w konsoli, a zdarzenie OnKeyPress dostarcza znak w parametrze Key. Jeśli ten parametr zawiera znak o kodzie 13 to znaczy, że wciśnięto Enter i to masz wybadać warunkiem.

za pomocą zapamiętanej w dodatkowym polu referencji, załaduj ten obrazek do kontrolki.

Zadeklaruj sobie dodatkową zmienną, do której wpisz Sender w zdarzeniu OnClick. Następnie w zdarzeniu OnKeyPress użyj tej zmiennej do załadowania obrazka.


Przykładowego kodu niestety nie podrzucę, bo od Borlanda używałem jedynie Delphi i w ogóle nie znam ichniejszego dialektu C++. Jeśli nie rozumiesz o czym piszę to musisz przysiąść i nauczyć się podstaw języka, bo bez tego ani rusz.

0

Wielkie dzięki!!, oczywiście, że siadam. :) nie ma innej opcji;)


znalazłem wiele przykładów użycia Sender.
próbuję kilka z nich, np.:

void __fastcall TSUDOkumacz::P1Click(TObject *Sender)
{
int x=(TImage*)Sender)->Left;
int y=(TImage*)Sender)->Top;
Edit1->Visible=true;
}

podczas kompilacji zgłasza błąd: cannot convert 'TImage*' to 'int'. w parametrach Left i Top nie ma int?

0

Ale czy aby na pewno to się kompiluje? Poprawnie powinno być tak:

void __fastcall TSUDOkumacz::P1Click(TObject Sender)
{
  int x=((TImage*)Sender)->Left;
  int y=((TImage*)Sender)->Top;
  Edit1->Visible=true;
}

Pominę już fakt korzystania z rzutowania w stylu C w C++.

Trochę się przyczepię do tego co @furious programming napisał. Ja tam jestem leniwy i nie pamiętam, że enter to 13. Bardziej elegancko będzie jak będzie się korzystało z tego http://docwiki.embarcadero.com/RADStudio/Seattle/en/Virtual_Key_Codes oraz VK_RETURN :)

0
Mr.YaHooo napisał(a):

Ja tam jestem leniwy i nie pamiętam, że enter to 13. Bardziej elegancko będzie jak będzie się korzystało z tego http://docwiki.embarcadero.com/RADStudio/Seattle/en/Virtual_Key_Codes oraz VK_RETURN :)

Tak, tyle że sam jestem pascalowcem, więc u mnie VK_RETURN jako integer nie może być wykorzystany do bezpośredniego porównania ze zmienną typu Char – trzeba albo rzutować któryś operand, albo przeciążyć sobie operator. A że w libce standardowej nie ma stałych z kodami znaków sterujących typu Char, to najczęściej używam po prostu #13.

Ale nie wiem jak to wygląda w C++, dlatego podałem kod klawisza, a nie nazwę stałej. ;)

0

@furious programming to tego nie byłem świadom, że tylko w C++ tak jest. Tam piszę po prostu:

void __fastcall TForm1::OnKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
  if (Key == VK_RETURN)
  {

  }
}

I to działa bez zbędnych ostrzeżeń oraz rzutowań.

0

@Mr.YaHooo: w Pascalu jest zbyt silne typowanie, aby takie coś było możliwe.

Poza tym nie pisałem o zdarzeniu OnKeyDown, a o OnKeyPress. W nim dostajemy znak typu char odpowiadający wciśniętemu przyciskowi – dlatego miałem wątpliwości co do porównania i wolałem podać kod znaku.

0

Fjurius, idzie, idzie.. powoli, ale drę darń pazurami...

na podstawie podanej liczby określ ścieżkę obrazka i za pomocą zapamiętanej w dodatkowym polu referencji, załaduj ten obrazek do kontrolki.

obrazek wrzucam tak, np:

P1->Picture->LoadFromFile("img/pusto.bmp")

jak mógłbym zamiast pusto.bmp podać ścieżkę np. "img/num.bmp" , (gdzie num jest już integerem), w ten sposób, by zamiast num wpisywał wartość liczbową? Bo zamiast P1 będzie NazwaPola, referencja z Sendera.

Edyta redaguje: NazwaPola, które jest referencja z Sendera - Nie działa... byłoby za prosto.. ([C++ Error] Unit1.cpp(165): E2288 Pointer to structure required on left side of -> or ->*). Czyli teraz mam dwie zachwostki:

  • co podstawić za P1
  • jak podać ścieżkę dostępu , by wykorzystać wartość "num"
1
k1313 napisał(a):

jak mógłbym zamiast pusto.bmp podać ścieżkę np. "img/num.bmp" , (gdzie num jest już integerem), w ten sposób, by zamiast num wpisywał wartość liczbową?

Użyj numerka wpisanego do pola edycyjnego, mniej więcej na tej zasadzie:

P1->Picture->LoadFromFile("img\\" + Edit1->Text + ".bmp");

Tylko najpierw sprawdź, czy w polu edycyjnym użytkownik poprawnie wpisał cyferkę i czy w ogóle to zrobił.

0

Już...
Kiedy klikam na kontrolkę z obrazkiem P1, m.in. pobieram referencje:

int x=((TImage*)Sender)->Left;
int y=((TImage*)Sender)->Top;
NazwaPola=((TImage*)Sender)->Name;

potem otwiera się Edit1, tam wszystko, jak do tej pory gra i trąbi, oprócz tego, że w zależności z jakiego pola (P1, P2..itd) odpaliłem Edit, mam tam umieścić obrazek, czyli pod OnKeyDown Edita1:

P1->Picture->LoadFromFile("img\\"+Edit1->Text+".jpg");

tyle, że zamiast P1 chciałbym wstawić referencję kontrolki odpalającej, np NazwaPola.

pytanie poza konkursem - dlaczego tam działa Edit1->Text, a już zmienna np. cyfra_str, która ma wartość Edit1->Text, tam nie działa?

2

Po to sugerowałem Ci zadeklarowanie sobie dodatkowego pola w klasie formularza, abyś nie musiał w kółko rzutować na konkretny typ i abyś nie musiał cudować z zapamiętywaniem i wykorzystywaniem nazwy komponentu. Czytasz w ogóle co piszę? Bo wydaje mi się, że w ogóle.


Zadeklaruj więc to dodatkowe pole w klasie formularza:

TImage* ActiveImage;

W zdarzeniu OnClick kontrolki z obrazkiem najpierw wpisz do tego pola referencję klikniętego komponentu:

ActiveImage = (TImage*)Sender;

W dalszej części tego zdarzenia pobierz współrzędne tej kontrolki i oblicz współrzędne do wyświetlenia pola edycyjnego. Wszystko zrób na podstawie dodatkowego pola, żebyś nie musiał za każdym razem rzutować:

Edit->Left = ActiveImage->Left + (ActiveImage->Width - Edit->Width) / 2;
Edit->Top = ActiveImage->Top + (ActiveImage->Height - Edit->Height) / 2;

Edit->Show();

Natomiast w zdarzeniu OnKeyPress czy tam OnKeyDown, sprawdź czy stuknięto w Enter i czy podana w polu edycyjnym wartość zawiera poprawną cyferkę. Jak już to wykonasz to wykorzystaj tę dodatkową zmienną do załadowania obrazka do właściwego komponentu, a następnie ukryj pole edycyjne:

ActiveImage->Picture->LoadFromFile("img\\" + Edit->Text + ".jpg");
Edit->Hide();

To wszystko. Nie wiem czy składniowo ten kod jest poprawny, ale nie używam C++, więc sam to sprawdź. Jeśli dzielenie za pomocą / nie może być użyte do obliczeń na liczbach całkowitych, to wynik trzeba będzie zaokrąglić np. za pomocą Round.

0

dzięki!
rozumiem, że wygląda to tak, jakbym nie czytał..;) czytam po kilkanaście razy, nie kumam po prostu czasem jak to zrobić, więc próbuję po swojemu, żeby o każdą duperelę nie pytać... wiem, że to nie są skomplikowane rzeczy, ale ja mam przed sobą całą górę. muszę na nią wejść krok po kroku.
jeszcze raz wielkie dzięki za poświęcany czas! bezcenne! nie dostanę tego nawet z mastercarda;)
potem zabiorę się za projekt i ew. dam znać

1 użytkowników online, w tym zalogowanych: 0, gości: 1