Dynamiczne Formy z użyciem obecnych form

Wątek zablokowany 2014-06-18 17:26 przez flowCRANE.

0

Witam.

Otóż chciałbym sobie utworzyć dynamicznie formę na zasadzie "zrób kopię istniejącej już formy ze zmianami" ale nie umiem przyporządkować nowej formie schematu, zmiennych itp istniejącej już formy.

Próbowałem już metody przypisania NewForm := Form2; ale to nie za bardzo działało gdyż można było utworzyć tylko jedną formę.
Jeszcze jest opcja żeby robić wszystko od początku na zasadzie kodu ale jest z tym więcej pracy.
Co mam zrobić aby nowo utworzona forma przyjęła wszystkie atrybuty, komponenty oraz funkcje i procedury obecnej formy ? I tak żeby można było utworzyć kilka takich form.

Proszę o pomoc w rozwiązaniu problemu.

1

Użyj TFrame

0

Próbowałem już metody przypisania NewForm := Form2; ale to nie za bardzo działało gdyż można było utworzyć tylko jedną formę.

Jedyne co w ten sposób zrobiłeś to przepisałeś adres instancji klasy z jednej zmiennej do drugiej, przez co dwie zmienne wskazywały na ten sam obiekt formularza;

Jeszcze jest opcja żeby robić wszystko od początku na zasadzie kodu ale jest z tym więcej pracy.

Możesz skopiować plik dfm, w którym zapisane sa informacje o danym formularzu, a resztę kodu skopiować w edytorze kodu;


Najlepiej użyć - tak jak napisał poprzednik - TFrame, bo właśnie do tego służy.

0
furious programming napisał(a):

Próbowałem już metody przypisania NewForm := Form2; ale to nie za bardzo działało gdyż można było utworzyć tylko jedną formę.

Jedyne co w ten sposób zrobiłeś to przepisałeś adres instancji klasy z jednej zmiennej do drugiej, przez co dwie zmienne wskazywały na ten sam obiekt formularza;

Jeszcze jest opcja żeby robić wszystko od początku na zasadzie kodu ale jest z tym więcej pracy.

Możesz skopiować plik dfm, w którym zapisane sa informacje o danym formularzu, a resztę kodu skopiować w edytorze kodu;


Najlepiej użyć - tak jak napisał poprzednik - TFrame, bo właśnie do tego służy.

Naprawdę, kopiować DFM'a i kod w notatniku?
Poza tym - czy Wy naprawdę nie słyszeliście o dziedziczeniu, a w szczególności o wizualnym dziedziczeniu form w Delphi?
Przecież to jest banał - klikasz w menu Delphi IDE:

  1. File->New->Other
  2. Wybierasz opcję "Inheritable Items"
  3. IDE wyświetla wszystkie formy w projekcie
  4. Wybierasz tę którą chcesz "skopiować", czyli dziedziczysz
  5. Klikasz OK
    I masz nową instancję formy, która jest w 100% odpowiednikiem rodzica.
    To jest metoda dla klikaczy... ;-)

To samo można zrobić z kodu - zapominacie, że forma jest klasą i można utworzyć wiele instancji tej samej klasy.
Zwyczajnie, jak każdej innej - czyli:

var 
  Form1,
  Form2 : TMyForm;
begin
  Form1 := TMyForm.Create(Application);
  Form2 := TMyForm.Create(Application);
end;

I masz dwie niezależne instancję tej samej formy, z którymi możesz zrobić co chcesz.

Co do ramek - nie lubię ich, nie używam i uważam, że nie mają (dla mnie) żadnej przewagi nad zwykłymi formami, za to mają kilka istotnych ograniczeń.
Ktoś może powiedzieć "skoro tak, to jak umieścić formę na formie, tak jak ramkę na formie?".
Zwyczajnie - zadokować ją.

0

Mi chodzi bardziej o dynamiczne tworzenie tych form.
Mam jedną formę bazową powiedzmy formę z paroma editami.
Powiedzmy naciskam na przycisk ile razy chcę i tyle razy otwierają mi się koleje formy wyglądające tak samo jak ta bazowa.

Dodatkowo z TFrame mam ten sam problem bo ni jak się odwołać przy dynamicznym tworzeniu:
NewForm := TForm.Create(self);
NewFrame := TFrame.Create ??

0
TForm1.Create(Application).Show;

Pamiętaj aby zwolnić.

1
chkam napisał(a):

Mi chodzi bardziej o dynamiczne tworzenie tych form.
Mam jedną formę bazową powiedzmy formę z paroma editami.
Powiedzmy naciskam na przycisk ile razy chcę i tyle razy otwierają mi się koleje formy wyglądające tak samo jak ta bazowa.

Przecież napisałem Ci jak [CIACH!].
Dobrze, teraz wersja dla sześciolatka:

procedure TForm27.Button1Click(Sender: TObject);
begin
  with TForm28.Create(Application) do
  begin
    ManualDock(PageControl1);
    Caption := Format('Nowa forma nr %d', [PageControl1.PageCount]);
  end;
end;

Oraz kompletny projekt w załączniku...

Oczywiście może to być forma modalna, MDI albo dynamicznie dokowana na PageControl jak w moim przykładzie.
Możesz dokować formę na innych formach.
Możesz zrobić z nią co zechcesz, jedyne ograniczenie to Twoja wyobraźnia...

Dodatkowo z TFrame mam ten sam problem bo ni jak się odwołać przy dynamicznym tworzeniu:

Bo co? Bo "ni jak się odwołać"? A co to dokładnie znaczy?

NewForm := TForm.Create(self);
NewFrame := TFrame.Create ??

0
_13th_Dragon napisał(a):
TForm1.Create(Application).Show;

Pamiętaj aby zwolnić.

W tym konkretnym przypadku nie trzeba zwalniać - forma zostanie zwolniona, kiedy zwolniony będzie jej właściciel - w tym przypadku właścicielem formy jest aplikacja.
A więc kiedy aplikacja będzie zamykana, najpierw zwolnione zostaną wszystkie komponenty dzieci.
Ten mechanizm działa od zawsze dla każdej klasy będącej potomkiem TComponent, gdyż jest immanentną cechą VCLa.

0

Ok teraz zauważyłem o co chodzi xD

  • Znalazłem nawet prostszy sposób:
 procedure FormClone(form : TForm) ;
 var
    ms : TMemoryStream;
    clone : TForm;
 begin
    ms := TMemoryStream.Create;
    try
      ms.WriteComponent(form) ;
      ms.Position := 0;
      clone := TFormClass(form.ClassType).CreateNew(Application) ;
      ms.ReadComponent(clone) ;
 
      clone.Left := form.Left + 10;
      clone.Top := form.Top + 10;
      clone.Show;
    finally
      ms.Free;
    end;
 end;

dodanie znacznika <code class="delphi"> - furious programming

1

Napisałeś 80% niepotrzebnego kodu (z czego wnoszę, że nie masz do końca pojęcia co napisałeś) - gratuluję!
To się nazywa prostszy sposób... wiesz że to Twoje "cudo" faktycznie skopiuje Ci kontrolki, ale ich logiki (mam na myśli kod w zdarzeniach formy, kontrolek, czy inny kod w klasie formy) już nie?
Ergo - wygląd będzie identyczny, działanie będzie żadne.

0

Do _13th_Dragon

@wloochacz, mówisz: - "Nie napisałem nigdzie, że są trzymane w pamięci, jak są niepotrzebne", a ten post to co?

A ten post to przykład na dynamiczne tworzenie formatek, bez zarządzania cyklem ich życia.
Pytacz miał problem z dynamicznym tworzeniem formatki, a nie jej zwalnianiem ;-)

Ja napisałem że trzeba pamiętać aby zwolnić a ty się czepiasz że samo się zwolni.

Nie czepiam się, tylko wskazałem na pewną istotną cechę VCLa a której, być może, pytacz nie wie.
I tylko to było moją intencją.

Zauważ ciężko tą formatkę użyć ponownie bo nie ma nigdzie do niej uchwytu (oprócz Application.Components),

Gdybym się czepiał, to zwróciłbym Ci uwagę, że wyrażasz się nieprecyzyjnie bo nie chodzi o uchwyt (Handle) a o referencję na obiekt formatki...
Poza tym, nie tylko w Application.Components, ale też Screen.Forms i na pewno również w PageControl.Page.Controls, a stąd już łatwo pozyskać referencję na formę zadokowaną na konkretnej zakładce TPageControl.
Oczywiście to i tak dookoła, bo powinno się to zrobić inaczej - np. stosując polimorfizm i lekko napisać TPageControl czy TTabSheet.
Nie łap nie proszę za słówka, bo to daremne, a przede wszystkim jeszcze raz powtarzam - moją intencją nie było łapanie za słówka Ciebie.

więc gwarantowane na 100% że nie myślałeś o ponownym jej użyciu (no chyba że kompletnie nie znasz Delphi a to raczej wykluczam).

Oczywiście, że nie myślałem bo nie o to chodziło w mojej odpowiedzi...


Do **furious programming** Pisałem o forum w ten sposób "*sorry, ale poziom tego forum jest żenujący; nie ma jakiejś piaskownicy albo coś?*", a nie o konkretnym użytkowniku - rozumiesz różnicę? Możesz sobie dawać bana na całego (ani mnie to grzeje, ani ziębi), traktuję "dostęp do forum" jako odskocznię i jeśli potrafię, to pomagam innym stosując się do "[[http://4programmers.net/Forum/Delphi_Pascal/39079-Zanim_cos_napiszesz_-_CZYTAJ_TO|regulaminu]]" w którym napisano: "*Forum jest miejscem dla inteligentnych ludzi, ja zawsze staram się podać drogę do rozwiązania problemu, a nie od razu rozwiązanie.*" No to nie podaję od razu całościowego rozwiązania, zamiast tego prowokuję do myślenia i dyskusji... A że poziom jest żenujący? Bo JEST! Oczywiście nie wszystkich postów... Tak czy inaczej, jeśli tego nie widzisz, to kto ma to widzieć? I skąd ja mam wiedzieć, że dany użytkownik jest "mniej wiedzący" - powiedz mi skąd? To napisz publicznie - za co **dokładnie** chcesz dać mi bana? Rozumiem, że zależy Ci na ilości i wzajemnej adoracji nawet jak wszyscy będą pisali piramidalne bzdury? A jakość postów jest dla Ciebie mało istotna? Zawsze wydawało mi się, że taki moderator powinien dbać o użytkowników forum, którzy mają coś istotnego do powiedzenia i chcą dzielić się swoją wiedzą i doświadczeniem z innymi - **za darmo**. A jakim Ty jesteś moderatorem?

I na koniec - przypomnij mi proszę poprzednie te dwa ostrzeżenia, ok?
Jakoś nie widzę, abym kogokolwiek obraził z Tobą włącznie, nawet w tym poście.
Już raz mnie próbowałeś obrazić - to był pierwszy i ostatni raz.

1

Tak czy inaczej, jeśli tego nie widzisz, to kto ma to widzieć? I skąd ja mam wiedzieć, że dany użytkownik jest "mniej wiedzący" - powiedz mi skąd?

Skoro forum jest dla inteligentnych ludzi i sam zapewne uważasz się za osobę inteligentną, to jakim cudem nie widzisz tego, że pytacz mniej wie od Ciebie? Oczywiste jest, że skoro zadał tutaj pytanie, na które nie zna odpowiedzi, a Ty ją znasz, to wiesz od niego więcej (przynajmniej w poruszanej sprawie);

Tak samo, skoro uważasz się za osobę inteligentną, to dlaczego wypisujesz takie durnoty o piaskownicy? Osoba inteligentna nie musi się żalić tym w publicznej części serwisu - dobrze to rozumie i wie, że inni użytkownicy na pewno też mają takie wrażenie; Ja też uważam, że bardzo dużo pytań na tym forum nie powinno się pojawiać, bo odpowiedzi można samemu znaleźć w kursach czy Google, ale nie wypisuję takich głupot, bo to do niczego pożytecznego nie prowadzi; Wręcz przeciwnie - takie zachowanie prowokuje do awantury, a raczej Tobie - jako osobie inteligentnej - nie muszę przypominać, jakim terminem określa się użytkowników, prowokujących innych swoimi wypowiedziami;

To napisz publicznie - za co dokładnie chcesz dać mi bana?

Odposujesz na mój komentarz, a skoro nadal nie wiesz za co, to znaczy że go w ogóle nie przeczytałeś; A napisałem go właśnie publicznie, żebyś zarówno Ty go zobaczył, jak i inni użytkownicy; Więc napiszę Ci jeszcze raz - za gnojenie użytkowników i prowokowanie do awantury, retorycznie pytając się czy nie ma dla takich użytkowników forumowej piaskownicy; Przekaz jest jasny - Ty jesteś wszystkowiecącym kozakiem (co już wielokrotnie widać było w Twoich postach, jak bardzo wysokie mniemanie masz o sobie), a pytacz mający problem z podstawowym zagadnieniem jest upośledzonym debilem, którego odesłać trzeba do forumowej piaskownicy czy żłobka, niech się hello-worldem pobawi, bo według Ciebie na tyle go stać; Nie mam na myśli niniejszego wątku, tylko piszę ogólnie;

Rozumiem, że zależy Ci na ilości i wzajemnej adoracji nawet jak wszyscy będą pisali piramidalne bzdury? A jakość postów jest dla Ciebie mało istotna?

Mój komentarz jest krótki i zwięzły, a jednak kompletnie nic nie zrozumiałeś; Zależy mi na tym, abyś szanował (i każdy inny) nawet najbardziej opornych użytkowników, nawet praktycznie nic nie wiedzących, czy porywających się z motyką na słońce; Napisałem Ci już wcześniej - nie podoba Ci się poziom zaawansowania pytań na forum czy poziom wyszkolenia pytaczy, to nie zaglądaj na forum, bo nie potrafisz się powstrzymać od wypisywania prowokujących tekstów i szydzenia z początkujących; Udzielanie się na forum to przywilej, a nie obowiązek, więc jeśli wkurza Cię niski poziom pytaczy, to nie musisz w ogóle odpowiadać - tak jak napisałem Ci już wcześniej w innym wątku - nie odpisuj, zaoszczędzisz sobie i nam nerwów;

Zawsze wydawało mi się, że taki moderator powinien dbać o użytkowników forum, którzy mają coś istotnego do powiedzenia i chcą dzielić się swoją wiedzą i doświadczeniem z innymi - za darmo.

Tak, staram się dbać o wszystkich - zarówno o guru, użytkowników wielokrotnie więcej wiedzących ode mnie i innych, jak i o całkowicie początkujących; Moderator ma dbać o porządek na forum, mniej o dobro informacji przkazywanych przez użytkowników; Każdego można upomnieć w sposób kulturalny, mp. "Pomyliłeś się", "To nie tak" czy inne, a nie od razu "gdzie jest piaskownica" czy inne bzdury; Ja wolę napisać grzecznie, że "rozwiązanie jest tutaj - mogłeś poszukać w Google, zajęłoby to 5 minut", ale Ty już nie; Postępujesz dokładnie tak, jak już dawno temu opisano to w artykule dotyczącym cyklu rozwoju programisty; Ty jesteś na końcu zaawansowania tej ścieżki - uważasz że zjadłeś wszystkie rozumy i możesz bezgranicznie wyżywać się na początkujących, wykazując ich głupotę i bezmyślność, zamiast brak wiedzy (a to ogromna różnica);

Po drugie - wszyscy rozwijamy to forum za darmo, zarówno użytkownicy, jak i moderatorzy czy administratorzy; Poświęcamy swój prywatny czas aby pomagać innym; Ja to robię z satysfakcji, pomaganie innym daje mi wiele radości i czuję się szczęśliwy, jeśli komuś pomogę;

A jakim Ty jesteś moderatorem?

Nie napiszę Ci tego, bo to była by ocena subiektywna; Załóż wątek w odpowiednim dziale - np. Społeczność, w którym zrób ankietę i zachęć użytkowników do zagłosowania i ocenienia mojego wkładu zarówno w rozwój serwisu, jak i w odsetek rozwiązanych problemów;

Nie wiem czy inni to widzą, w każdym razie forum przeglądam codziennie, poświęcając łącznie około 3-5 godzin dziennie na przeglądnięcie wszystkich nowych wątków w działach Newbie i Delphi/Pascal: poprawiam tytułu wątków, uzupełniam tagi, wstawiam znaczniki kolorujące składnię, usuwam prowokujące posty, dodaję obrazki do załączników, formatuję posty, przypominam użytkownikom o zachowaniu porządku i nie kłóceniu się, rzadko banuję - to ostateczność; Więcej czasu poświęcam na sprzątanie forum, niż na pomaganie pytaczom, bo niestety nie zdążam odpowiadać w czasie, bo najpierw poprawiam co trzeba poprawić; Do tego pomagam w rozwoju serwisu przez zgłaszanie błędów czy niedociągnięć w dziale Coyote; Uczestniczę w dyskusjach zamkniętych na temat rozwoju seriwsu i trzymania porządku na forum; Niedawno objąłem funkcję moderatora globalnego, więc i czasem poprawki wnoszę w innych działach, w których poruszane są problemy, których nie potrafię rozwiązać - nie mogę pomóc pytaczowi, ale formatuję posty;

Jeśli chcesz wiedzieć ile poprawek wprowadziłem na forum - zgłoś się do administracji, która wyciągnie z bazy logi na temat poprawianych, przenoszonych i usuwanych postach; Nie chcę się chwalić, ale takie logi były już raz wyciągnięte (bodaj po kilku miesiącach objęcia przeze mnie funkcji moderatora) i zajmowałem jedno z najwyższych miejc, w porównaniu do innych moderatorów; Dlaczego? Bo uwielbiam porządek i chcę, aby wszyscy użytkownicy odwiedzający moderowane przeze mnie działy przeglądali ładne wątki, ze sformatowaną treścią; To było dwa lata temu - teraz ta liczba będzie kilkakrotnie większa, co oznacza ogrom mojego wkładu w rozwój forum i trzymanie porządku;

Jako użytkownik - staram się pomagać wszystkim, bez docinek; Odpowiadam w każdym wątku, w którym potrafię coś doradzić czy znam rozwiązanie; Dyskutuję z różnymi użytkownikami przez PM, w różnych sprawach - tworzenia postów, gdzie podaję linki do artukułów, w których opisane są sposoby formatowania postów, zachowania na forum, o sprawach prywatnych, gdzie rozmiawiamy luźno o różnych rzeczach, na temat zleceń itd. itp.; Zarówno o ilości napisanych postów, komentarzy, ilości wątków, w których brałem udział jak i ilości rozwiązanych przeze mnie problemów świadczy moja reputacja - proszę zobaczyć sobie do mojego profilu, w którym możesz ją sprawdzić, a także liczniki postów i ich rozkład na działy; Jest tam wykres, przedstawiający ten rozkład - ponad 80% wszystkich postów napisałem w działach technicznych, głównie Delphi/Pascal oraz Newbie;

Do tego poprawiam artykuły znajdujące się w odpowiednim dziale serwisu, sam napisałem kilka, które choć trochę interesują użytkowników; Jakieś pół roku temu skontaktował się ze mną użytkownik, który mój atrykuł dotyczący "generowania słów metodą znaczników" chciał i wykorzystał w swoim dużym komercyjnym projekcie, dotyczącym projektowania sieci kanalizacyjnej, bazującej na sieciach neuronowych; Do dziś jestem w szoku, bo nie sądziłem, że taki prosty algorytm może mieć tak szerokie zastosowanie; Z mojego artykułu dotyczącego tworzenia "własnych okien dialogowych" także skorzystało bardzo dużo początkujących; Więc co najmniej kilku użytkownikom pomogłem - bardzo mnie to cieszy; Obserwuje mnie na dzień dzisiejszy czterech użytkowników - być może chcą się czegoś ode mnie nauczyć, co również jest dla mnie ogromnym wyróżnieniem, bo nie uważam się za guru, wręcz przeciwnie - jeszcze mnóstwa rzeczy nie wiem (nawet sam znalazłeś taką rzecz - wizualne dziedziczenie formularzy, czego nie znam);

Kolejną rzeczą jest projekt plików konfiguracyjnych; Jeszcze nie upublikowałem projektu, a już miałem kilka PMek z pytaniami i prośbami, abym ruszył tyłek i opublikował projekt, bo kilku użytkowników jest nim zainteresowanych; O tym także świadczy ilość plusików w moim mikroblogu, dzięki którym po pierwsze - jest jakieś zainteresowanie, po drugie - wygrałem kubeczek, za co serdecznie dziękuję użytkownikom - właśnie popijam z niego kawkę; Nad tym projektem pracuję dla siebie i dla Was - użytkowników 4programmers; Opublikuję go oczywiście na przygotowanej stronie, a także na tym forum; Wiem, że programistów Delphi i Object Pascala jest tutaj dużo, więc chcę się z Wami podzielić moim projektem, nad którym pracuję już ponad rok - za darmo, i za darmo go rozdam, aby każdy mógł z niego skorzystać lub jego kod wykorzystać w czym tylko chce;

I na koniec - przypomnij mi proszę poprzednie te dwa ostrzeżenia, ok?

No i znowu nie zrozumiełeś; Napisałem w komentarzu, że to już drugi raz (łącznie z obecnym wątkiem), a za trzecim zostaniesz zbanowany; Chcesz linka? Proszę bardzo - w tym wątku gnoiłeś pytacza (choć wcale nie początkujacego) swoimi głupimi tekstami, tym razem o przedszkolu - nie o piaskownicy; W niniejszym wątku dostałeś drugie ostrzeżenie; Kolejne - ban;

Jakoś nie widzę, abym kogokolwiek obraził z Tobą włącznie, nawet w tym poście.

Napisałbym Ci dlaczego nie widzisz (nie pamiętasz), ale to zbędne;

Już raz mnie próbowałeś obrazić - to był pierwszy i ostatni raz.

Nigdy nie próbowałem Cię obrazić, a przypomnieć abyś szanwał wszystkich użytkowników; Ale Ty tego nie możesz zrobić, bo masz zbyt wysokie mniemanie o sobie; Mnie już kilka razy udupiłeś (a raczej moją niewiedzę z programowania i omylność), za co bardzo Ci dziękuję - uświadomiłeś mi, jak jeszcze wiele muszę się nauczyć; Choć Twoje posty nie były najmilsze, to i tak dobrze, że napisałeś tak, a nie inaczej;


Podsumowując - jeśli masz jakieś wątpliwości czy uwagi na temat mojej funkcji moderatora, to nie rób syfu na forum i albo zapraszam na PM, gdzie sobie podyskutujemy, albo zgłoś to do administracji, gdzie odpowiednie osoby zajmą się tą sprawą i widząc moją winę ukarają mnie; Poza tym zachęcam do przeprowadzenia ankiety na temat pożytku z udzielania się na forum przeze mnie - zobaczymy, czy użytkownicy widzą we mnie kogoś pożytecznego i pomocnego, czy tylko kolejnego zbędnego czy nic nie wnoszącego użytkownika;

A na koniec - jeśli odnosisz się do mojej wypowiedzi, to bądź łaskaw przywołać mnie klauzulą @furious programming, abym dostał powiadomienie i dowiedział się co o mnie czy do mnie piszesz; Muszę Cię zmartwić, ale żaden wątek i żaden post w dwóch głównych działach które moderuję, nie umknie mojej uwadze, więc bądź pewny, że nieprzywoływanie mnie odpowiednią klauzulą nic Ci nie da - i tak prędzej czy później trafię na taki post, przeczytam go i skomentuję;

Jeśli masz coś jeszcze do powiedzenia w tej sprawie, to tak jak napisałem wyżej - PM do mnie lub raport do administracji.

0

Jeszcze jedno małe pytanko odnośnie dostępu do tych utworzonych form. (Akurat użytych w wersji MDI).

var
  i : integer;
begin
  for i := 0 to Application.MainForm.MDIChildCount - 1 do begin
    if (Application.MainForm.MDIChildren[i].Name = 'Contact1') then begin
      MainForm.MDIChildren[i].Destroy;
      Exit;
    end;
  end;

Użyłem takiego kodu do usuwania form jeżeli są już zbędne z poziomu innego okna, ale jak teraz się dostać do poszczególnych komponentów danego okna. Kiedyś używałem

TComponent(FindComponent('Nazwa')).Właściwość := NoweDane;

Tak więc spróbowałem użyć to na formie:

TFormContact(FindComponent('Contact1')).NazwaKomponentu.Właściwość := NoweDane;

ale niestety ta próba przyniosła wynik negatywny, a poprzedni kod pozwala tylko na działania w obrębie właściwości formy ale też nie wszystkich.

0

Odpowiedź na pytanie:

TComponent(MainForm.MDIChildren[i].FindComponent('Nazwa')).Właściwość:=NoweDane;

Ale nie rób tego!
Zrób normalny wskaźnik na okienko, może listę takich wskaźników.
Na formie też nie szukaj komponenty wg nazwy zrób normalne wskaźniki ewentualnie tablice.

2

OKiej, @chkam, zatem skupmy się na tym co nie działa, czyli "importem danych do okna"...
Co dokładnie rozumiesz przez ten import danych i co Ci nie działa?
Rzuć kawałkiem kodu z aplikacji... nie chcę zgadywać.
Napisałeś:

[...] teraz chciałem to wszystko przerobić tak abym mógł obsługiwać kilka rzeczy naraz. Na początek chciałem użyć do tego wielu form ale na koniec zdecydowałem się na wersję (MDI).

O co chodzi z tymi kilkoma rzeczami naraz?
Nie rozumiem też tego tekstu o wielu formach - przecież MDI to też wiele form..

BTW - na pewno chcesz robić to na MDI? Nie wiem czy zauważyłeś, ale MDI jest od jakiegoś czasu passe - spójrz na np. MS Outlook ;-)

0

Tak więc opiszę o co chodzi @wloochacz.
Chodzi o to że chciałbym otworzyć powiedzmy kilka kontaktów jednocześnie czyli:

Mam obecnie procedurę tworzącą formę

procedure TMainForm.NewFormContact(Sender: TObject);
var
  NewContact : TForm_Contact;
begin
  ContactCount := ContactCount + 1;
  NewContact := TForm_Contact.Create;
  NewContact.Caption := 'Contact';
  NewContact.Left := 16;
  NewContact.Top := 16;
  NewContact.Name := 'Contact' + IntToStr( ContactCount );
  NewContact.Show;
end;

Teraz mam kolejne okno MDI podobnie utworzone (TForm_Contact_List) które jest listą kontaktów:

procedure TForm_Contact_List.Button_NewContact(Sender: TObject);
begin
  MainForm.NewFormContact(Sender: TObject);
end;

Do tej pory jest wszystko ok dopóki nie chcę zapełnić editów znajdujących się w tym nowym oknie które chce utworzyć.

procedure TForm_Contact_List.Button_NewContact(Sender: TObject);
var
  NewFormName : string;
  i : integer;
  ContactFile : INIFile;
begin
  ContactFile := TINIFile.Create( ContactDir + '\' + FileListBox.Items.Strings[ FileListBox.ItemIndex ] );
  MainForm.NewFormContact(Sender: TObject);
  NewFormName := 'Contact' + IntToStr(ContactCount);
  // I Teraz chciałbym uzupełnić znajdujące się tam pola
  for i := 0 to Application.MainForm.MDIChildCount - 1 do begin
    if (Application.MainForm.MDIChildren[i].Name = NewFormName ) then begin
      try
      //...Edit1.Caption := DeCode( ContactFile.ReadString( 'MAIN', 'Name', ' ' ), Password );
      //...Edit2.Caption := DeCode( ContactFile.ReadString( 'MAIN', 'Surname', ' ' ), Password );
      // itd
      finally
      ContactFile.Free;
      end;
  end;
end;

I właśnie tu mam problem bo nie wiem jak się odwołać do tych editów, wiem jak się forma nazywa bo przy tworzeniu pobieram nazwę do zmiennej.

I jeszcze jest kolejny problem, forma z listą kontaktów chociaż może być tylko jedna otwarta w tym samym czasie to muszę po kliknięciu przycisku zapisz w formie edycji kontaktu na formie listy zaktualizować FileListBox.

procedure TForm_Contact_List.Button_Save(Sender: TObject);
var
  i : integer;
beginm
  // pomińmy już zapis do pliku
  for i := 0 to Application.MainForm.MDIChildCount - 1 do begin
    if (Application.MainForm.MDIChildren[i].Name = 'Form_Contact_List' ) then begin
      // Tutaj chcę się odnieść do procedury aktualizującej formy Form_Contact_List
      // ...RefreshContacts(Sender); 
    end;
  end;
end;  

(...) - powinno tutaj być odwołanie do formy a potem jej komponentów oraz procedur

0

@chkam,
Wieczorkiem opisze Ci co i jak, ale jeszcze dwa pytania...

  1. Jakiej wersji Delphi używasz? To istotne.
  2. Nie chcesz użyć do tego jakiejś bazy danych? Np. wbudowanej lub innej, w miarę prostej która nie wymaga instalacji itd.
0

OK @chkam, skoro masz XE5 to takie coś robi się ot tak z wykorzystaniem serializacji (obiektów lub rekordów - jak chcesz. Delphi ma to wbudowane, jest tez od metra gotowców w sieci.) i LiveBindings. Ale pewnie nie wiesz o czym piszę lub z innych względów nie możesz tak zrobić, więc darujmy sobie to.
A Twój problem polega na prostym rzutowaniu.
Co do bazy danych - imo popełniasz błąd - baz danych to dziś absolutny must have.

OK - zaraz opisze co i jak...

1

@chkam, w Twoim kodzie są błędy, ale jak rozumiem to taki pseudo-kod a nie gotowiec do kompilacji.

Wypełnianie editów:

procedure TForm_Contact_List.Button_NewContact(Sender: TObject);
var
  NewFormName : string;
  i : integer;
  ContactFile : INIFile;
  lContactForm : TForm_Contact;
begin
  ContactFile := TINIFile.Create( ContactDir + '\' + FileListBox.Items.Strings[ FileListBox.ItemIndex ] );
  MainForm.NewFormContact(Sender: TObject);
  NewFormName := 'Contact' + IntToStr(ContactCount);

  // I Teraz chciałbym uzupełnić znajdujące się tam pola
  for i := 0 to Application.MainForm.MDIChildCount - 1 do begin
    if (Application.MainForm.MDIChildren[i].Name = NewFormName) and (Application.MainForm.MDIChildren[i] is TForm_Contact) then 
    begin
      try
        lContactForm := Application.MainForm.MDIChildren[i] as TForm_Contact;
        lContactForm.Edit1.Caption := DeCode( ContactFile.ReadString( 'MAIN', 'Name', ' ' ), Password );
        lContactForm.Edit2.Caption := DeCode( ContactFile.ReadString( 'MAIN', 'Surname', ' ' ), Password );
        // itd
      finally
      ContactFile.Free;
      end;
      Break;
    end;
end;

Aktualizacja listy kontaktów:

procedure TForm_Contact_List.Button_Save(Sender: TObject);
var
  i : integer;
  lContactList : TForm_Contact_List;
beginm
  // pomińmy już zapis do pliku
  for i := 0 to Application.MainForm.MDIChildCount - 1 do 
    if (Application.MainForm.MDIChildren[i].Name = 'Form_Contact_List') and (Application.MainForm.MDIChildren[i] is TForm_Contact_List) then 
    begin
      lContactList  := Application.MainForm.MDIChildren[i] as TForm_Contact_List;
      // Tutaj chcę się odnieść do procedury aktualizującej formy Form_Contact_List
      lContactList.RefreshContacts(Sender); 
      Break;
    end;
end;

I tyle.
Ale!
Bez względu co na to powie @furious programming jest to tandeta i druciarstwo. Nie powinno się tak pisać programu, mimo że będzie działać. Zwłaszcza w Delphi XE5, które na pokładzie daje spore możliwości w zakresie bindingu obiektów do kontrolek i serializacji danych.
Można to pięknie napisać zgodnie z wzorcem MVC lub MVVM.

0

trzeba coś odpisać @furious programming, żeby sobie nie pomyślał tego co mógłby sobie pomyśleć... ;-)
Słuchaj człowieku - nie mam zamiaru i ochoty się z Tobą przerzucać czyj jest dłuższy. Na grupach dyskusyjnych siedzę od ponad 10 lat, przez ten czas pomogłem dziesiątki jeśli nie setki razy - i co z tego? Nic. A może mam Ci pokazać nad czym pracuję? Mogę, ale po co - 90% tej grupy nie uwierzy, że tak się da pisać w Delphi, a 80% tego nie zrozumie. Co w Twoich oczach czyni mnie bufoniastym bucem. Niech będzie - był czas przywyknąć.
Ale mam też się czym pochwalić - 2x dałem się namówić na wykład na zlocie programistów Delphi i 2x byłem na pudle. Było i tak że mój współpracownik i ja zdobyliśmy 2 i 3 miejsce za najlepszy wykład (nagradzane były 3 na kilkanaście).
Nie wiem czy ktoś jeszcze z Polski miał dostęp do developerskiego repo SVN AnyDAC'a oprócz mnie - a nie dostaje się czegoś takiego za bluzgi na grupach.
Tak więc, bardzo Cię proszę - wyluzuj...

Mam taki a nie inny styl pisania, który nie jest idealny (eufemistycznie rzecz ujmując) - zgoda. Ale mam w nosie utyskiwania niedouczonych leni. Średni raz na kwartał mam zarzuty, że jestem "niemiły" na grupie dyskusyjnej. Zawsze mówię, żeby sobie do KFa mnie dodał i nie będzie musiał się męczyć. Tylko jakoś nikt tego nie robi...

Reasumując - wezmę sobie Twoje uwagi do serca, ale odpuść sobie wycieczki w stylu "nie wszyscy są tak inteligentni jak ty", a ja postaram się nie używać skrótów myślowych i pisać w miarę zrozumiale lub wcale.
Nie obiecuję, że mnie czasem ciut za daleko nie poniesie - taka już moja "uroda" ;-)

0

à propos livebindings - sam mam xe5, widzialem kilka tutoriali o tej technologii, ale dla mnie to jest tylko poglebianie klikania i zaciemnianie kodu - tracimy nie jako kontrole nad kodem - cos tam w tle sie binduje ze soba, mozemy sobie graficznie poprzeciagac polaczenia, ale czy tedy droga?

moze sie myle, moze ktos mnie pouczy albo przekona, jednak sadze ze nie wszystko zloto co sie swieci, nie kazde nowosci sa dobre,
to samo powiedzialbym o FireMoneky, ale to juz temat rzeka.... pozdrawiam

0
co22312 napisał(a):

à propos livebindings - sam mam xe5, widzialem kilka tutoriali o tej technologii, ale dla mnie to jest tylko poglebianie klikania i zaciemnianie kodu - tracimy nie jako kontrole nad kodem - cos tam w tle sie binduje ze soba, mozemy sobie graficznie poprzeciagac polaczenia, ale czy tedy droga?

No cóż... niestety nie zrozumiałeś o co w tym wszystkim chodzi, co dla programisty przyzwyczajonego do tradycyjnego podejścia Delphi-RAD jest zupełnie normalną sprawą.
Dlaczego? Dlatego, że to zupełnie nowe podejście w światku Delphi i zupełnie normalne np. w .NET.

Trochę się z Tobą zgadzam, ale bardziej nie.
Faktem jest, że to co można zobaczyć na oficjalnych prezentacjach woła o pomstę do nieba. Chłopaki z Emba chcieli zrobić binding obiektów w sposób wizualny, czyli zgodny z RADowym podejściem Delphi. No i wyszedł niejako taki potworek jak wizualny edytor LiveBindings. Na szczęście nie trzeba go używać, a można używać go z poziomu kodu do naprawdę ciekawych rzeczy.
A więc nie tylko do bindowania kontrolek z obiektami, ale też np. do obliczania wyrażeń w locie - czyli coś takiego:

  TPerson = class
  strict private
    FName: string;
    FSurname: string;
    procedure SetName(const aValue: string);
    procedure SetSurname(const aValue: string);
  public
    property Name: string read FName write SetName;
    property Surname: string read FSurname write SetSurname;
  end;

implementation

procedure Some;
var
  lPersons : TList<TPerson>;
  lPerson  : TPerson;
begin
  lPersons := TList<TPerson>.Create;
  // wypełnienianie listy danymi - nieistotne w tej chwili

  for lPerson in lPersons.Where('Surname like kowal%') do
  begin
    // zrób coś tam z elementami listy, które spełniają warunek: nazwisko zaczyna się od kowal
  end;
end;

Rozumiem, że kod napisany w ten sposób nie jest dla Ciebie czymś co warto mieć na pokładzie?
Ja wiem, że można to napisać zupełnie inaczej - ale nie o to chodzi.
Poza tym w ten sposób można filtrować listę dowolnych obiektów, bez konieczności implementacji funkcji sprawdzającej warunek.

Co do bindingu - chcesz mi powiedzieć, że mechanizm który umożliwia dynamicznie reagowanie na zmianę właściwości jednego obiektu jest niepotrzebne?
OK, skoro chcesz wszystko pisać ręcznie i za każdym razem poprawiać kiedy zmienisz obiekt lub jego prezentację, to proszę bardzo.
Ale osobiście uważam swój czas za zbyt cenny na marnowanie go na takie banały.

I absolutnie nie zgadzam się z tezą, że nie masz nad tym kontroli.
Masz pełną kontrolę, tylko trzeba zmienić sposób programowania z używania obiektów na programowanie obiektowe.
Pewnie, że wymaga to więcej wiedzy i zachodu. Ale samo utrzymanie i rozwój projektu napisanego w ten sposób jest wielokrotnie prostsze, szybsze i tańsze.

I tak uważam, to tędy droga - to otwiera zupełnie nowe możliwości, a jedną z nich są dostępne ORMy dla Delphi.
Oczywiście można dyskutować o niuansach technicznych, ale co do zasady - w końcu są takie możliwości w Delphi.
10 lat za późno, ale dobrze że są.

co22312 napisał(a):

moze sie myle, moze ktos mnie pouczy albo przekona, jednak sadze ze nie wszystko zloto co sie swieci, nie kazde nowosci sa dobre,
to samo powiedzialbym o FireMoneky, ale to juz temat rzeka.... pozdrawiam

FMX to jest bardzo dobry pomysł (nie wiem czy wiesz, ale Emba kupiło tę technologię i kiedyś nazywało się to GLScene i DXScene) i średnie wykonanie. Na szczęście z wersji na wersję jest coraz lepiej.

PS.
Podobne filtrowanie list generycznych zrobiłem sobie z wykorzystaniem... FireDAc'a. Mało kto wie, że w FireDAC/AnyDAC dostępny jest całkiem fajny, otwarty "expression framework".

0

Ciekawe rzeczy piszesz, zgadzam sie ze FM jest pomyslem fajnym, jednak wykonanie kuleje.
co do LiveBindings to nie zgłębiałem się w sumie w temat, brakuje mi czasu na wertowanie internetu w poszukiwaniu tajemnych technik uzywania nowych delphiowych rzeczy.
Przyznaje ze to co pokazales w przykladzie jest dla mnie nowoscia ale jestem ciekawy kto oprocz Ciebie wiedzial o czyms takim w delphi i tego uzywa.
A to co pokazales to mi przypomina EntityFramework z C#...

0
co22312 napisał(a):

Ciekawe rzeczy piszesz, zgadzam sie ze FM jest pomyslem fajnym, jednak wykonanie kuleje.

Zgoda, ale jest coraz lepiej. Zauważ że taki framework to ewenement - podobny jest .NETowy WPF, ale FMX jest multiplatform!

co do LiveBindings to nie zgłębiałem się w sumie w temat, brakuje mi czasu na wertowanie internetu w poszukiwaniu tajemnych technik uzywania nowych delphiowych rzeczy.
Przyznaje ze to co pokazales w przykladzie jest dla mnie nowoscia ale jestem ciekawy kto oprocz Ciebie wiedzial o czyms takim w delphi i tego uzywa.
A to co pokazales to mi przypomina EntityFramework z C#...

Ciutke przypomina.
Ale znacznie więcej jest np. w DORM lub TMS Aurelius
Oczywiście nie należy zapominać o Spring for Delphi i ich doskonałych kolekcjach, ale nie tylko. Osobiście intensywnie korzystam z kontenerów IoC i oczywiście wstrzykiwania zależności.

Kto o tym wie?
Nie wiem kto o tym nie wie - znam mnóstwo ludzi którzy wiedzą i korzystają ;-)

0

HEHE, skoro obracasz się środowisku samych zawodowców Delphi to gratuluję i zazdroszczę :)

Wstyd a może nie, ale programuje w Delphi kilka lat i pierwszy raz słyszę o jakiś dobrych frameworkach do delphi.
CHyba jeszcze mnie czeka trochę nauki na stare lata ;)

PS. Jest szansa żeby pogadać z Tobą gdzieś na privie na tematy delphiowe, czy może nie udzielasz audiencji :) ?

0

Pisz, najwyżej nie odpowiem. Mogę też zniknąć na jakiś czas - prowadzę firmę i mam wdrożenia własnego oprogramowania, poza tym nie samym programowaniem człowiek żyje. A przynajmniej nie ja ;-)
Uczciwie przyznaję, że nie jestem specem od wszystkiego. Najlepiej czuję się w architekturze, wzorcach, OOP i oczywiście w bazach danych. RTLa i VCLa pomijam bo to absolutne must-have.
A np. nie cierpię wizualnego układania kontrolek w Delphi.

Dość powiedzieć, że w moim autorskim systemie nie robię formatek w sposób wizualny - w ogóle ich nie robię. Wskazuję co ma być prezentowane i w jaki sposób a reszta się dzieje. Aczkolwiek celowo to pomijam (w sensie nie chcę pokazywać kodu), bo to naprawdę nic nie wniesie do dyskusji, a dojście do takich rezultatów wymaga sporo pracy.

Tak samo jestem absolutnym przeciwnikiem stosowania komponentów bazodanowych w aplikacji w sposób "standardowy" - czyli umieszczamy TQuery gdzieś (forma, datamodule) i oprogramowujemy zdarzenia. Takie podejście uważam za strzał w stopę, kolano i głowę i, co to owijać w bawełnę, amatorszczyznę.
Dałbym spokój, gdyby to był sobie takie post - ale jak ktoś mówi "pokaże Wam jak się powinno pisać program bazodanowy" to sorry... To jest może i dobre (wróć - nie, nie jest dobre) do pisania czegoś na szybko i na kolanie.
Tak na marginesie - przeraża mnie ilość niepotrzebnego kodu, który ludzie piszą aby obsłużyć standardowe zachowania. Zwłaszcza w aplikacji bazodanowej większość podstawowych operacji da się ustandaryzować. I naprawdę nie trzeba tworzyć np. osobnego formularza do wyszukiwania danych dla każdej encji...

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.