prozedur ausführen wenn Hauptform vollständig geladen?

Für Fragen von Einsteigern und Programmieranfängern...
gemo1905
Beiträge: 8
Registriert: So 8. Jul 2012, 21:03

prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von gemo1905 »

Hallo,
ich habe vor ca.1 Jahr angefangen lazarus zu lernen!
Hatte hauptsächlich nur mit Tstinglist gearbeitet.
Nun entwerfen ich ein CAD cam Programm für 2d Brennzuschnitte. Nun mein Problem. Im oncreat meiner Hauptform erstelle ich eine "leere" CAD Datei (tstringlist). Indieser sind aber schon Informationen zum zeichnen stehen.
Ich habe einen Button der die Datei komplett neu zeichnet! Wenn ich das Programm starte und den Button anklicke dann funktioniert alles super.

Wenn ich Button.click in onformactive oder onshow ausführen dann passiert nicht bzw. kommen Darstellungsfehler!Diesefalsche Darstellung kommt "denke ich" da ich Abhängig von meiner tpaintbox (width und hight) zeichne. Das habe ich mitbekommen als ich weitere Elemente programmiert habe und einen Fehler wegen Division durch 0 bekommen habe! Das passiert bei manuellem Buttonklicken nicht.
Entschuldigt bitte alle Fehler. Das ist alles vom Handy aus geschrieben.
MFG George
Also wie kann ich diese Prozedur aufrufen wenn die Form vollständig geladen ist?

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von theo »

Der beste Moment zum zeichnen ist eigentlich das OnPaint Ereignis.

gocher
Beiträge: 298
Registriert: Di 23. Nov 2010, 23:41
OS, Lazarus, FPC: Ubuntu/Win, Lazarus trunk, FPC trunk
CPU-Target: 32Bit/64Bit
Wohnort: Geldern
Kontaktdaten:

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von gocher »

ich würde eine Funktion schreiben in der ich den Inhalt der Button.onClick Funktion ablegen würde, dann bräuchte ich kein onClick-Event ausführen, sondern nur die Funktion aufrufen, sowohl im Form.onShow wie auch im Button.onClick.
Damit hätte ich schon einmal ausgeschlossen das das onClick-Event zu dem Augenblick noch nicht zur Verfügung steht!
OnPaint wir meiner Meinung bei jeder Veränderung des Forms aufgerufen, das könnte zu Problemen führen.
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von Scotty »

Das ist eine FAQ; es gibt eine ganze Reihe von Lösungen, die auch irgendwann hier diskutiert wurden. Mein Favorit ist Application.OnIdle zu benutzen.

Code: Alles auswählen

procedure TForm1.OnCreate()
begin
  Application.OnIdle:=@DoIdle;
end;
 
procedure TForm1.DoIdle()
begin
  ...
  OnIdle:=nil;
end;

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von theo »

gocher hat geschrieben: OnPaint wir meiner Meinung bei jeder Veränderung des Forms aufgerufen, das könnte zu Problemen führen.
Wieso? OnPaint ist der einzig "sichere" Moment zum zeichnen.

Eb
Lazarusforum e. V.
Beiträge: 240
Registriert: Di 5. Feb 2008, 15:32
OS, Lazarus, FPC: Linux Mint - Laz 2.2.0
CPU-Target: 64Bit
Wohnort: Stuttgart

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von Eb »

gocher hat geschrieben:
procedure TForm1.OnCreate()
begin
Application.OnIdle:=@DoIdle;
end;

procedure TForm1.DoIdle()
begin
...
OnIdle:=nil;
end;
Habe ich das richtig verstanden, dass TForm1.DoIdle() genau einmal ausgeführt wird,
und dass zu diesem Zeitpunkt alle Steuerelemente die sich auf Form1 befinden vollständig vorhanden sind?

Bora4d
Beiträge: 290
Registriert: Mo 24. Dez 2007, 13:14
OS, Lazarus, FPC: WinXP-Pro-Sp3, Xubuntu 12.04, (Laz 1.1-SVN Mai2012, FPC 2.6.1 / 2.6.0-Linux)
CPU-Target: AMD64X2

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von Bora4d »

Nein OnIdle wird ausgeführt wenn das PRogramm nicht beschäftigt ist.

Wie Theo gesagt hast wird das immer bei OnPaint gemacht, das ist normale Vorgehensweise.

Was auch gut ist du Plazierst ein TImage und zeichest da drin einmal und es reicht.

Wenn du TImage benutzen willst kannst du das in Forms OnCreate machen, z.B:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
begin
 Image1.Canvas.Brush.Color := clWhite;
 Image1.Canvas.FillRect(0, 0, Width, Height);
 Image1.Canvas.TextOut(10,10,'Hello');
end;

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von Scotty »

Da OnIdle in DoIdle() auf nil gesetzt wird, wird diese Funktion auch nicht nochmal aufgerufen. Mag sein, dass dein Problem mit OnPaint() besser gelöst ist; ich muss zugeben, deine Frage nicht 100%ig verstanden zu haben. Meine Buttons zeichnen jedenfalls nicht 8) ("Ich habe einen Button der die Datei komplett neu zeichnet!")

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von theo »

Scotty hat geschrieben: Mein Favorit ist Application.OnIdle zu benutzen.
Naja, dann lieber OnShow, da weiss man wenigstens, was das für ein Zeitpunkt ist.
OnIdle ist ja nicht genauer definiert, im "Erstellungsablauf" eines Formulars.

gocher
Beiträge: 298
Registriert: Di 23. Nov 2010, 23:41
OS, Lazarus, FPC: Ubuntu/Win, Lazarus trunk, FPC trunk
CPU-Target: 32Bit/64Bit
Wohnort: Geldern
Kontaktdaten:

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von gocher »

Eb hat geschrieben:
gocher hat geschrieben:
procedure TForm1.OnCreate()
begin
Application.OnIdle:=@DoIdle;
end;

procedure TForm1.DoIdle()
begin
...
OnIdle:=nil;
end;
Nein das habe ich nicht geschrieben, sondern Scotty!

Ich glaube einfach daran das gemo1905 einfach etwas falsch macht was wir nie herausfinden werden solange wir nicht wissen was in Button.onClick passiert und wie er Button.onClick aufruft!

So funktioniert das aufrufen des Button.onClick, was machst Du anders oder was machst Du in Deiner Procedure?
Bitte melde Dich gemo1905!

Code: Alles auswählen

unit uForm1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, LResources, Forms,
  Graphics, Controls, Dialogs, StdCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption := 'Test';
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1Click(Sender);
end;
 
end.
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me

gemo1905
Beiträge: 8
Registriert: So 8. Jul 2012, 21:03

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von gemo1905 »

Hallo und erstmal Danke für die viele Hilfe!!!

Also den Tipp mit der eignen Prozedur habe ich versucht, aber wieder wird nichts gezeichnet.

Onpaint wird immer aufgeführt wenn sich das gesamte "Bild" der Form ändert, bzw. Allgemein der Desktop.
Ich habe am Anfang meiner "Zeichnen" Prozedur eine Showmessage('Test'); eingebunden um zu sehen wann bzw. wie oft die Prozedur aufgerufen wird.
Selbst bei Onshow sehe ich meine Message und im Hintergrund ist noch keine Hauptform zu sehen!
Ich stelle dann gleich nochmal meinen unübersichtlichen :cry: Quelltext rein.(Muss nur mein Win booten)

Da ich wiegesagt Anfänger bin werden viele Mein Quelltext unübersichtlich finden!

Dank euch habe ich aber jetzt zum ersten mal eigene function's und Prozeduren erstellt.

Man lernt immer Stück für Stück zu :D

MfG George

gemo1905
Beiträge: 8
Registriert: So 8. Jul 2012, 21:03

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von gemo1905 »

Code: Alles auswählen

procedure TForm_main.CAD_Refresh;
var
   linie, linie2:string;
   farbe:string;
   zaehler, zaehler2, point:integer;
   Abmass_x, abmass_y, faktor_x, faktor_y:real;
   X_draw_mm_1, X_draw_mm_2, Y_draw_mm_1, Y_draw_mm_2:real;
   X_draw_pix_1, X_draw_pix_2, Y_draw_pix_1, Y_draw_pix_2:integer;
   Xneu, Yneu:real;
begin
  //showmessage('test');
  cadbox.Canvas.Brush.Color:=clblack;
  cadbox.Canvas.Brush.Style:=bssolid;
  cadbox.Canvas.FillRect(0,0,cadbox.Width,cadbox.Height);
   with cad_file do
     begin//Informationen auslesen
        if indexof('#~Block1')=-1 then
           begin
              showmessage('Fehler: Datei Fehlerhaft(Informationen fehlen)!');
              exit;
           end else
           begin
              zaehler:=0;
              repeat
                 linie:=strings[indexof('#~Block1')+zaehler];
                 if linie='Abmaß'
                    then begin
                         Abmass_X:=strtofloat(strings[indexof('#~Block1')+zaehler+1]);
                         Abmass_Y:=strtofloat(strings[indexof('#~Block1')+zaehler+2]);
                         if Abmass_X=0 then Abmass_X:=100;
                         if Abmass_Y=0 then Abmass_Y:=100;
                         Min_view:=strtofloat(cad_temp.Strings[cad_temp.IndexOf('MIN_view')+1]);
                         faktor_x:=Min_view/(cadbox.Width-(2*cad_rand));
                         faktor_y:=Min_view/(cadbox.height-(2*cad_rand));
                         if faktor_x>=faktor_y
                            then faktor:=faktor_X
                            else faktor:=faktor_Y;
                         end;
                 inc (zaehler);
              until linie='#~~';
           end;
     end;
     with cad_file do
       begin///Hilfslinien zeichnen!!
        if indexof('#~Block4')=-1 then
           begin
              showmessage('Fehler: Datei Fehlerhaft(Hilfslinien fehlen)!');
              exit;
           end else
           begin
              zaehler:=0;
              repeat
                 linie:=strings[indexof('#~Block4')+zaehler];
                 if linie='Linie'
                    then begin
                    X_draw_mm_1:=strtofloat(strings[indexof('#~Block4')+zaehler+1]);
                    Y_draw_mm_1:=strtofloat(strings[indexof('#~Block4')+zaehler+2])*-1;
                    X_draw_mm_2:=strtofloat(strings[indexof('#~Block4')+zaehler+3]);
                    Y_draw_mm_2:=strtofloat(strings[indexof('#~Block4')+zaehler+4])*-1;
                    //Punkte linear anpassen
                    //STEIGUNG___m=(y2-y1)/(x2-x1)
                    edit_cad.Text:=floattostr(X_draw_mm_2-X_draw_mm_1);
 
                    X_draw_pix_1:=round(   ((X_draw_mm_1-MP_CAD_X)/faktor)+cadbox.Width  div  2  );
                    Y_draw_pix_1:=round(   ((Y_draw_mm_1+MP_CAD_Y)/faktor)+cadbox.Height div 2   );
                    X_draw_pix_2:=round(   ((X_draw_mm_2-MP_CAD_X)/faktor)+cadbox.Width  div  2  );
                    Y_draw_pix_2:=round(   ((Y_draw_mm_2+MP_CAD_Y)/faktor)+cadbox.Height div 2   );
                    //zeichnen
                    cadbox.Canvas.Pen.Style:=psDashDot;
                    cadbox.Canvas.Pen.Color:=clred;
                    cadbox.Canvas.Line(X_draw_pix_1, Y_draw_pix_1, X_draw_pix_2, Y_draw_pix_2);
                    inc(zaehler,4);
                    end;
                 inc(zaehler);
              until linie='#~~' ;
           end;
       end;
 
       with cad_file do
         begin///KONTUREN!!!zeichnen!!
          if indexof('#~Block3')=-1 then
             begin
                showmessage('Fehler: Datei Fehlerhaft(Block3 fehlt)!');
                exit;
             end else
             begin
                zaehler:=0;
                repeat
                   linie:=strings[indexof('#~Block3')+zaehler];
                   if linie=#9+'31' //wenn KONTURTYP 31 (geschlossene Kontur)
                      then begin
                         repeat
                            //Konturtyp:=strings[indexof('#~Block3')+zaehler+1];
                            //reserve:=strings[indexof('#~Block3')+zaehler+2];
                            //reserve:=strings[indexof('#~Block3')+zaehler+3];
                            //reserve:=strings[indexof('#~Block3')+zaehler+4];
                            //reserve:=strings[indexof('#~Block3')+zaehler+5];
                            //reserve:=strings[indexof('#~Block3')+zaehler+6];
                            //reserve:=strings[indexof('#~Block3')+zaehler+7];
                            //reserve:=strings[indexof('#~Block3')+zaehler+8];
                            //reserve:=strings[indexof('#~Block3')+zaehler+9];
                            //reserve:=strings[indexof('#~Block3')+zaehler+10];
                            linie:=strings[indexof('#~Block3')+zaehler];
                            if Linie='Linie' then //wenn Linie dann zeichne Linie
                               begin
                                  farbe:=strings[indexof('#~Block3')+zaehler+1];
                                  cadbox.Canvas.Pen.Color:=stringtocolor(farbe);
                                  linie:=strings[indexof('#~Block3')+zaehler+2];
                                  point:=strtoint(copy(linie,0,pos(' ',linie)-1));
                                  if cad_file.IndexOf('#~Block2')=-1 then showmessage('Fehler: Datei Fehlerhaft(Block3 fehlt)!')
                                     else begin
                                        zaehler2:=cad_file.IndexOf('#~Block2');
                                        while cad_file.Strings[zaehler2]<>'P'+Inttostr(Point) do inc(zaehler2);
                                        X_draw_mm_1:=strtofloat(cad_file.Strings[zaehler2+1]);
                                        Y_draw_mm_1:=strtofloat(cad_file.Strings[zaehler2+2])*-1;
                                     end;
                                  point:=strtoint(copy(linie,pos(' ', linie),length(linie)-pos(' ', linie)+1));
                                  //showmessage(inttostr(point));
                                        zaehler2:=cad_file.IndexOf('#~Block2');
                                        while cad_file.Strings[zaehler2]<>'P'+Inttostr(Point) do inc(zaehler2);
                                        X_draw_mm_2:=strtofloat(cad_file.Strings[zaehler2+1]);
                                        Y_draw_mm_2:=strtofloat(cad_file.Strings[zaehler2+2])*-1;
                                  X_draw_pix_1:=round(   ((X_draw_mm_1-MP_CAD_X)/faktor)+cadbox.Width  div  2  );
                                  Y_draw_pix_1:=round(   ((Y_draw_mm_1+MP_CAD_Y)/faktor)+cadbox.Height div 2   );
                                  X_draw_pix_2:=round(   ((X_draw_mm_2-MP_CAD_X)/faktor)+cadbox.Width  div  2  );
                                  Y_draw_pix_2:=round(   ((Y_draw_mm_2+MP_CAD_Y)/faktor)+cadbox.Height div 2   );
                                  //zeichnen
                                  cadbox.Canvas.Pen.Style:=pssolid;
                                  cadbox.Canvas.Line(X_draw_pix_1, Y_draw_pix_1, X_draw_pix_2, Y_draw_pix_2);
 
                               end;
                            inc(zaehler);
                         until Linie='EOK';
                      end;
                   inc(zaehler);
                until linie='#~~' ;
             end;
         end;
 
 
end;

gemo1905
Beiträge: 8
Registriert: So 8. Jul 2012, 21:03

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von gemo1905 »

Code: Alles auswählen

procedure TForm_main.Form_main_create(Sender: TObject);
begin
  //ALGEMEINE PARAMETER BEI START ERSTELLEN!!!
  cadbox.Canvas.Pen.Width:=1;
  //cadbox.Color:=clblack;
  cad_rand:=30;
  decimalseparator:='.';
  //CAD TEMP ERSTELLEN
  cad_temp:=Tstringlist.Create;
  cad_temp.Add('ViewMitte');
  cad_temp.Add('15');
  cad_temp.Add('15');
  cad_temp.Add('MIN_view');
  cad_temp.Add('30');
  //LEERES CAD FILE ANLEGEN
  cad_file:=Tstringlist.Create;
  cad_file.Add('#~Block1');
  cad_file.Add('Datum');
  cad_file.Add('01.03.2010');
  cad_file.Add('Abmaß');
  cad_file.Add('0');
  cad_file.Add('0');
  cad_file.Add('#~~');
  cad_file.Add('#~Block2');
  cad_file.Add('P1');
  cad_file.Add('0.0');
  cad_file.Add('0');
  cad_file.Add('P2');
  cad_file.Add('30');
  cad_file.Add('0');
  cad_file.Add('P3');
  cad_file.Add('0');
  cad_file.Add('30');
  cad_file.Add('#~~');
  cad_file.Add('#~Block3');
  cad_file.Add(#9+'31');
  cad_file.Add('IK');
  cad_file.Add('reserve');
  cad_file.Add('reserve');
  cad_file.Add('reserve');
  cad_file.Add('reserve');
  cad_file.Add('reserve');
  cad_file.Add('reserve');
  cad_file.Add('reserve');
  cad_file.Add('reserve');
  cad_file.Add('reserve');
  cad_file.Add('Linie');
  cad_file.Add('clwhite');
  cad_file.Add('1 2');
  cad_file.Add('Linie');
  cad_file.Add('clwhite');
  cad_file.Add('2 3');
  cad_file.Add('Linie');
  cad_file.Add('clwhite');
  cad_file.Add('3 1');
  cad_file.Add('EOK');
  cad_file.Add('#~~');
  cad_file.Add('#~Block4');
  cad_file.Add('Linie');
  cad_file.Add('0.000000000');
  cad_file.Add('0.000000000');
  cad_file.Add('0.000000000');
  cad_file.Add('1000.000000000');
  cad_file.Add('Linie');
  cad_file.Add('0.000000000');
  cad_file.Add('0.000000000');
  cad_file.Add('10.000000000');
  cad_file.Add('0.000000000');
  cad_file.Add('#~~');
  cad_file.Add('#~EOF');
  cad_file.SaveToFile('C:\users\cnc\desktop\geometrie.cad');
end;

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von theo »

Deinen Quelltext finde ich gar nicht so entscheidend, aber du solltest immer in OnPaint zeichnen.
Du kannst das auch selber auslösen, indem du Invalidate aufrufst, dann wird wieder in OnPaint gezeichnet.

gemo1905
Beiträge: 8
Registriert: So 8. Jul 2012, 21:03

Re: prozedur ausführen wenn Hauptform vollständig geladen?

Beitrag von gemo1905 »

So die zwei versprochenen Prozeduren.

Der restliche Quelltext ist weniger interesant für mein Problem!

Wiegesagt zum Schluss hatte ich die Prozedur in einem Buttonclick ausgeführt.

PS: wenn ich nicht so schnell Lösungen probieren kann und nicht gleich antworte dann habe ich keine Zeit gefunden :(

Vielen Dank nochmal euch allen!

MfG George

Antworten