ďťż

Ładny brzuch

Hello,
Today... - dobra piszę po polsku :)

Jak wiadomo dzień bez bug'a to dzień stracony dlatego jak zwykle jakiś się znalazł. Dzisiaj okazało się, że jest potrzebny mi jest wątek, który jest wykonywany w dynamicznie tworzonej formie - i tutaj właśnie jest problem, ponieważ kiedy próbuję się odwołać z wątku do jakiego komponentu na formie to wywala mi błąd (coś tam, że nie można odczytać czegoś z jakiegoś adresu ;) )

Pytanie: jak z wątku wykonywanego w dynamicznie tworzonej formie dostać się do komponentu na tej właśnie formie.

Za wszelką pomoc dziękuję

PS. Nie pisać mi, żebym nie korzystał z dynamicznej formy :)



Nie wiem czy dobrze rozumuje (proszę bez loli i bluzg jeśli myślę w odwrotnym kierunku!), ale może do klasy wątku dodaj pole typu tego komponentu. Np:

guzik: TButton;

i zrób konstruktor tej klasy, np tak:
constructor Create(guz: TButton); override;
i uzupełnij go w ten sposób:
constructor Twatek.Create(guz: TButton); begin guzik := guz; inherited Create(False); //normalne uruchomienie wątku end;

i w wątku odwołuj się do pola klasy zamiast bezpośrednio do komponentu.
Niestety tak jak mówię, naprawdę nie wiem, czy to o to chodzi. :unsure: :unsure: :unsure:

EDIT:
chociaż po głębszym zastanowieniu dochodzę do wniosku, że to na jedno wyjdzie (jesli w ogóle zadziała).
Użytkownik programista1101 edytował ten post 27 maj 2005, 18:36
Nie takie coś nie przechodzi - nie działa nawet tworzenie dynamiczne komponentu, którego potrzebuje (w kodzie nie ma błędu, lecz na formie nie pokazuje się on :( )

Może mam zły kodzik do tworzenia form dynamicznych. Posługuję się takim
with TForm2.Create(Self) do  try    ShowModal;  finally    Free;  end;

Nie używa się ShowModal przy dynamicznych formach, tylko [BShow[/B]. Najlepiej dać:Tworzenie formy: Form2:=TForm2.Create(Application); Wyświetlanie formy: Form2.Show; W OnClose dynamicznej formy: Form2.Destroy; I w OnClose pierwszej formy: Application.Terminate;
Użytkownik KSMłody edytował ten post 27 maj 2005, 20:10


KSMłody - Twój sposób nie pomógł. :(


Nie używa się ShowModal przy dynamicznych formach, tylko Show

Nie używa się czemu ?? Przecież w pomocy do Delphi jest ShowModal

-=PcSA=- a możesz gdzieś dać cały kod? Bo wtedy będzie można u siebie popróbowac, bez zbędnego zdagywania na forum.

EDIT:
//BTW przy wątkach powinno odwoływać się do innych procedur (może komponentów treż :unsure: ) poprzez Synchronioze. Odwołujesz się tak?

//BTW BTW kurcze - chyba nawijam nawinięte....
Użytkownik programista1101 edytował ten post 27 maj 2005, 20:29
Powiedz tylko czego, bo cały kod zajmuje 500 KB :)


EDIT:
//BTW przy wątkach powinno odwoływać się do innych procedur (może komponentów też  ) poprzez Synchronioze. Odwołujesz się tak?


Nie wiem nawet co to jest :)
Użytkownik -=PcSA=- edytował ten post 27 maj 2005, 20:30
Przy tworzeniu wątku za pomocą repozytorium Delphi daje taki komentarz:


{ Important: Methods and properties of objects in VCL or CLX can only be used
  in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure KLASA.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

Użytkownik programista1101 edytował ten post 27 maj 2005, 20:33
Lepiej dam kodzik wątku, bo Synchronize raczej chyba nie da się w tym przypadku użyć :(

Kodzik wątku: http://arturs.aplus....c.php?p=139#139

Jakbyś chciał jeszcze jakiś kawałek kodu to daj znać to dopiszę :)
Użytkownik -=PcSA=- edytował ten post 27 maj 2005, 20:35

Nie używa się czemu ?
Ha :D Udało mi się :). Zrobiłem tak (naturalnie dla przykładu):
Po koleji:

1. Zmienne globalne na Form1:
var forma: TForm; lb: TLabel; //w przykladzie odwolamy sie do TLabel;

2. procedura tworząca komponenty:
{wszytsko dla przykładu}  frm := Tform.Create(Application);  lb := TLabel.Create(frm);  lb.Parent := frm;  lb.SetBounds(10, 10, 100, 100);  lb.Caption := 'przed odwołaniem';  frm.Show;  lb.onclick := go;

3. Umieszczenie procedury "go" w delaracji klasy Form1:
type  TForm1 = class(TForm)   {...}  procedure go(sender: TObject);   {...}

4. Uzupełnienie procedury GO:

procedure TForm1.go(Sender: tObject); begin TMojWatek.Create(lb); end;

5. wyglad klasy watku:

uses  Classes, StdCtrls; {...} type  Tmojwatek = class(TThread)  myLab: TLabel;  protected    procedure Execute; override;  public    constructor Create(labelek: TLabel);    procedure napis;  end;

6. Uzupełnienie konstruktora:

constructor Tmojwatek.Create(labelek: TLabel); begin  mylab := labelek;  inherited Create(False); end;

7. Uzupełnienie procedury Execute:
procedure Tmojwatek.Execute; begin FreeOnTerminate := true; Synchronize(napis); end;

8. uzupełnienie procedury napis:

procedure Tmojwatek.napis; begin myLab.Caption := 'po odwołaniu do dynamicznego labela na dynamicznej formie z watku'; end;

Naturalnie to dla przykładu. Mam nadzieję, że po częsci udało się rozwiązać problem.
Użytkownik programista1101 edytował ten post 27 maj 2005, 21:02
Nie wiem - chyba ma pH. Niestety zrobiłem mniej więcej tak jak Ty to zrobiłeś (mniej więcej, bo chaiłem aby w Gauge coś się zmieniało) i nic nie działa - tzn. zawartość Gauge nie zmienia się - nie ma błędu ale nie zmienia się, a do tego wszystkiego nie mogę korzystać z funkcji zawartych w formie dynamicznie tworzonej :(

A jesli chodzi o ten postep. Masz tak:
for i:=-1 to IloscWpisow-1 do {....} ZamienHaslo.ProgressBar1.Position:= 1 + (i*7); //<- błąd {...} ZamienHaslo.ProgressBar1.Position:= 2 + (i*7); //<- błąd {...} ZamienHaslo.ProgressBar1.Position:= 3 + (i*7);

Przecież to logiczne, że jest błąd skoro "i" na początku jest ujemne.

EDIT:
Zrobilem u siebie też z Gauge i działa.

A jesli chcesz odwoływać się do funkcji i procedur w stworzonej formie to może dodaj parametr forma: TForm w konstruktorze oraz pole w klasie wątku? :unsure:
Użytkownik programista1101 edytował ten post 27 maj 2005, 22:10

A jesli chcesz odwoływać się do funkcji i procedur w stworzonej formie to może dodaj parametr forma: TForm w konstruktorze oraz pole w klasie wątku?

Tform w konstruktorze nie działa (chyba, że coś pomieszałem).

Co do Progress'a to się faktycznie wygłupiłem

A dodałeś do uses moduł Forms oraz pole TForm do klasy wątku? Bo u mnie działa.

BTW. Ale chyba można też wszystkie te funkcje i procedury formy dynamicznej umieścic w sekcji public dowolnej innej klasy...
Użytkownik programista1101 edytował ten post 28 maj 2005, 11:47
Pewnie, że w uses jest moduł Forms :)


BTW. Ale chyba można też wszystkie te funkcje i procedury formy dynamicznej umieścic w sekcji public dowolnej innej klasy...

Właśnie w tym rzecz, że teraz nie wiadomo dla czego kiedy wywołuję jakąś funkcję z formy dynamicznej to w funkcji podczas jej uruchomienia wywala błąd, który nie istnieje kiedy odpalę go już nie z wątku :kwasny:
Oczywiście nie muszę dodawać, że funkcje są w sekcji public

Co do pola TForm - możesz zaprezentować jakiś przykład, bo wydaje mi się, że źle robię to o czym piszesz :lol2:

Hmmm to teraz inaczej - nie używając konstruktra a wszystko dzieki sekcji public Form1. Cel: chcemy na dynamicznie stworzonej formie pokzywać postep na ProgressBar oraz w dowolnym momencie mieć możliwość odwoływania się do procedur/funkcji dla tej formy.

1. W sekcji private klasy TForm1 deklarujemy procedurę odpowiedzialną za stworzenie formy oraz komponentu.
 procedure CreateComponents;
2. W sekcji public klasy TForm1 deklraujemy zmienne typu potrzebych komponentów oraz procedury/funkcje do których potem chcemy się odwoływać. Dla przykłądu jedna procedurka:
forma: TForm; Progress1: TProgressBar; procedure OnShowFormy(Sender: TObject); procedure ProceduraFormyDynamicznej;
Procedura OnShowFormy(Sender: TObject); będzie nam służyć do uruchomienia wątku i bedzie wywołana przy pojawieniu sie formy dynamicznej.

3. uzupełniamy procedurę "CreateComponents":
procedure TForm1.CreateComponents; begin forma := TForm.Create(Application); progress1 := TprogressBar.Create(forma); progress1.Parent := forma; progress1.Max := 100; progress1.SetBounds(10, 10, 300, 20); forma.OnShow := OnShowFormy; //to nie jest konieczne - mozna dac cos dowolnego tu poprostru bedzie uruchomienie watku forma.Show; end;

4. uzupełniamy procedurę "OnShowFormy"
procedure TForm1.OnShowFormy(Sender: TObject); begin  TWatek.Create(False); end;

5. Uzupełniamy procedurę "ProceduraFormyDynamicznej" - przykładowo.
procedure TForm1.ProceduraFormyDynamicznej; begin if progress1.Position >= 50 then  ShowMessage('To już połowa! A dokładnie: ' + IntToStr(progress1.Position); end;

6. Tworzymy nowy moduł, dodajemy go do uses (najlepiej w sekcji implementation) i wstawiamy w niego klasę wątku:

type  TWatek = class(TThread)  private  protected    procedure Execute; override;  end;

7. uzupełniamy procedurę "Execute":
procedure TWatek.Execute; var i: integer; begin FreeOnTerminate := True; for i := 0 to 100 do begin   Form1.Progress1.Position := i;   Synchronize(Form1.ProceduraFormyDynamicznej);  end; end;

Jak widać w wątku pokazujemy postęp, a także wywołujemy zdeklarowana wcześniej procedurę. W module, gdzie jest klasa wątku nalezy dodac do uses moduł z klasą TForm1.

Gdzieś w kodzie modułu z klasa TForm jeden dajemy:
CreateComponents.

Jesli to nie zadziała to ja już nie jestem w stanie pomóc.
Użytkownik programista1101 edytował ten post 28 maj 2005, 12:30
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • zsf.htw.pl
  •