Vytvoření třídy – Delphi – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Vytvoření třídy – Delphi – Fórum – Programujte.comVytvoření třídy – Delphi – Fórum – Programujte.com

 

oxidián0
Grafoman
3. 5. 2018   #1
-
0
-

Aplikace

uc_heb1.pas:

unit Uc_heb1;
interface

uses
  WinTypes, WinProcs, Messages, ExtCtrls, Dialogs,
  StdCtrls, Controls, Graphics, Gauges, Classes,
  Forms, Menus, SysUtils,
  Uc_obr2,vyslheb, jmeno, book, Buttons,
  uspech,testfnt, Napoveda,antiwin,otviram,
  functions, konstanty,
  FileCtrl;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;

....
    allBigger1: TMenuItem;
...
end.

implementation ...

testy.pas:

 

unit Testy;

interface

uses
  WinTypes, WinProcs, Messages, ExtCtrls, Dialogs,
  StdCtrls, Controls, Classes, // Graphics, Gauges, 
  Forms, Menus, SysUtils,
  Uc_obr2,vyslheb, jmeno, book, Buttons,
//  uspech,testfnt, Napoveda,antiwin,otviram,
  functions, konstanty,
  FileCtrl;

type
  TTesty = class(TForm)
  private
    dir : string;
    i: integer;
    Nic: TMenuItem;
    N1: TMenuItem;

    langMenuItems : array of TMenuItem;
    SubMenuItems : Array of TMenuItem;
    SubMenuItemsLoaded : Array [0..maxTestItems-1] of boolean;
    TestyDirs, SubDirs : TStringList; // for folders search
    procedure readINI;
    procedure writeINI;
    procedure JazykyInitiate;
    procedure DynMenu;
    procedure upravmenu;
  public
    allBigger, skipFontTest, fontSizeSmall, fontSizeNormal, fontSizeLarge,
    difficultyEasy, difficultyNormal, difficultyHarder, difficultyHard,
    testyDirFound : Boolean;
    TestyDir : string;

    fileMenu: array [0..maxRecentFiles-1] of string;

    JazykyIndexy : TStrings;
    Jazyky : Array [0..maxTestItems-1] of string; // Language names ... associated with JazykyFolders
    JazykyFolders : Array [0..maxTestItems-1] of string; // Folder names associated with Jazyky menu items
    JazykySelected : Array [0..maxTestItems-1] of string; // Jazyky sub-folder folder specification
  end;

implementation

procedure TTesty.upravmenu;
var curFile: TMenuItem;
    i : integer;

begin

  for i:=1 to maxRecentFiles do
    begin
    if i=1 then
      begin
        if fileMenu[0]<>'' then N1.visible:=true
        else N1.visible:=false;
      end;

    curFile := FindComponent('file'+IntToStr(i*10 + 1)) as TMenuItem;
    if fileMenu[i-1]<>'' then
      begin
        curFile.visible := true;
        curFile.caption:=extractfilename(fileMenu[i-1]);
      end
    else
      curFile.visible := false;

    end; // end for
end;

procedure TTesty.readINI;
var line: String;
    f:textfile;
    i, c, size: integer;
    TestFolderInfo: TStrings;
begin
  if not fileexists(dir+'uc_heb.ini') then exit;
  try
    assignfile(f,dir+'uc_heb.ini');
    reset(f);
  except
    showmessage('Nelze otevrit soubor .ini s nastavenim.');
  end;
  if filesize(f)<1 then
     begin
     showmessage('Soubor .ini neobsahuje text.' );
     exit;
     end;

  allBigger := false;
  skipFontTest := false;
  repeat
    readln(f,line);
    if line[1]='[' then
    begin;
      if line='[allBigger]' then allBigger:=true;
      if line='[skipFontTest]' then skipFontTest:=true;
      if line='[fontSmall]' then fontSizeSmall := true
        else if line='[fontNormal]' then fontSizeNormal := true
        else if line='[fontLarge]' then fontSizeLarge := true;
      if line='[difficultyEasy]' then difficultyEasy := true
        else if line='[difficultyNormal]' then difficultyNormal := true
        else if line='[difficultyHarder]' then difficultyHarder := true
        else if line='[difficultyHard]' then difficultyHard := true;
    end;
  until (line='[TestyDir]') or (line='[TestyFolders]') or eof(f);

  testyDirFound := false;
  if line='[TestyDir]' then
    begin
     readln(f,TestyDir);
     if DirectoryExists(TestyDir) then
       testyDirFound := true;
     readln(f,line);
    end;

  c := maxTestItems-1;
  if (line='[TestyFolders]') and (testyDirFound=true) then
    begin
    TestFolderInfo := TStringList.Create;
    for i:=0 to maxTestFolders-1 do
      begin;
        readln(f,line);
        TestFolderInfo.clear;
        try
          // ExtractStrings([';'],[],PChar(Str),Line)
          ExtractStrings([';'],[],PChar(line), TestFolderInfo);
          if (line='') or ( (line[1]='0') and (trim(line)='0;' ) ) then
            begin
              SubMenuItemsLoaded[i] := false;
              JazykyFolders[i] := '';
              JazykySelected[i] := '';
              continue;
            end;
{
JazykyIndexy - byly iniciovány v
JazykyInitiate. Seznam obsahuje jen prázdné řetězce.
}



{
NESMYSL! JazykyIndexy JEŠTĚ NENÍ PŘIPRAVENO!
          if ( TestFolderInfo.count > 0 ) then
            pos := JazykyIndexy.IndexOf(TestFolderInfo.Strings[0])
          else
            pos := -1;
}

          begin
             if (TestFolderInfo.Strings[0][1] = '[') or
             ( length(trim(TestFolderInfo.Strings[0])) = 0 ) then
               break; // ukončit smyčku přidávání jazyků

             Jazyky[i] := TestFolderInfo.Strings[0];

             SubMenuItemsLoaded[i] := true;
             JazykyFolders[i] := TestFolderInfo.Strings[0];
             if not (DirectoryExists(TestyDir+'\'+JazykyFolders[i])) then
                begin
                   CreateDir(TestyDir+'\'+JazykyFolders[i]);
                   showmessage(TestyDir);
                   showmessage('Adresář jsem zkusil vytvořit automaticky: '+TestyDir+'\'+JazykyFolders[i]);
                   ; JazykyFolders[i] := '';
                   SubMenuItemsLoaded[i] := false;
                end
             else
              try
                c := c-1; // potvrdit, že složka s jazykem byla asociována
// Jazyky sub-folder folder specification
// nemá být číslo, ale název adresáře

                if TestFolderInfo.count>2 then
                  JazykySelected[i] :=  TestFolderInfo.Strings[2]
                else
                  JazykySelected[i] := 'textbook';

                if not (DirectoryExists(TestyDir+'\'+JazykyFolders[i]+'\'+JazykySelected[i])) then
                  begin
                    CreateDir(TestyDir+'\'+JazykyFolders[i]+'\'+JazykySelected[i]);
                    showmessage('Adresar ucebnice jsem musel vytvorit: '+TestyDir+'\'+JazykyFolders[i]+'\'+JazykySelected[i]);
                  end;
              finally
              end;
          end;

         SubMenuItemsLoaded[i] := false
        finally
        end;
      end; // end of for ... begin

//    setlength( Jazyky, i+1 );
    TestFolderInfo.Free;
    end;

    // prevent crash: initiate arrays for DynMenu
    for i:=0 to maxTestItems-c-1 do
      begin
           JazykyFolders[i] := '';
           SubMenuItemsLoaded[i] := false;
      end;
    // end of else

  repeat
    readln(f,line);
  until ( line='[poslední testy]')  or eof(f);

  if line='[poslední testy]' then
    begin
    for i:=0 to maxRecentFiles-1 do
      fileMenu[i]:='';
    i:=0;
    repeat
      readln(f,fileMenu[i]);
      inc(i);
    until ((fileMenu[i]<>'') or (i=maxRecentFiles-1)) or eof(f);
    end;
  upravmenu;
  closefile(f);  {**************************************** to jsem tam dal ja!!!!}
end;

procedure TTesty.writeINI;
var f:textfile;
    b:boolean;
begin
try
 b:=false;
 assignfile(f,dir+'uc_heb.ini');
 try
   rewrite(f);
   b:=true;
   if allBigger1.checked then writeln(f,'[allBigger]');
   if skipFontTest1.checked then writeln(f,'[skipFontTest]');
   if fontSizeSmall1.checked then writeln(f,'[fontSmall]')
     else if fontSizeNormal1.checked then writeln(f,'[fontNormal]')
     else if fontSizeLarge1.checked then writeln(f,'[fontLarge]');
   if difficultyEasy1.checked then writeln(f,'[difficultyEasy]')
     else if difficultyNormal1.checked then writeln(f,'[difficultyNormal]')
     else if difficultyHarder1.checked then writeln(f,'[difficultyHarder]')
     else if difficultyHard1.checked then writeln(f,'[difficultyHard]');
   writeln(f,'[TestyDir]');
   writeln(f,TestyDir);
   writeln(f,'[TestyFolders]');
   for i:=0 to maxTestFolders-1 do
    begin
      if (Jazyky[i][1]=' ') or (Jazyky[i][1]='-') then
         continue; // skip Test menu Groups or Select
      if JazykySelected[i]='' then
         begin
          writeln(f,Jazyky[i]+';0');
          continue; // submenu not selected - done
         end
      else
         if (JazykySelected[i][1]=' ') or (JazykySelected[i][1]='-') then
           continue; // skip Test sub-menu Groups or Select

      if SubMenuItemsLoaded[i]=true then
        begin
          writeln(f,submenuItems[i].name+';'+JazykyFolders[i]+';'+JazykySelected[i])
        end
      else
        writeln(f,Jazyky[i]+';0');
    end;
   writeln(f,'[poslední testy]');
   for i:=0 to maxRecentFiles-1 do
      if fileMenu[i]<>'' then
        writeln(f,fileMenu[i]);
 except
   showmessage('Nastavení se nepovedlo zapsat.');
 end;
 closefile(f);
except
end;
end;


end.

Chyba: na řádku 234 v souboru testy.pas není známý identifikátor

allBigger1

v souboru uc_heb1.pas je tato definice:

allBigger1: TMenuItem;

je to tedy součást TForm1 ...

A teď mi řekněte jak v té třídě TTesty mám tedy zpřístupnit nebo odkázat na menu, které se používá v té třídě TForm1?

Navíc TTesty má být použito v TForm1.

Nahlásit jako SPAM
IP: 78.102.61.–
gna
~ Anonymní uživatel
1891 příspěvků
3. 5. 2018   #2
-
0
-

A nechceš náhodou zapisovat ty booleany, do kterých to načítáš?

Odkaz na form nebo cokoliv jiného můžeš do objektu předat stejně jako kdykoliv cokoliv jiného. Jako parametr jeho metody, nebo nastavením jeho proměnné.

Nakonec je ten Form1 pravděpodobně globální proměnná, tak to můžeš prostě napsat jako Form1.něco.

Nahlásit jako SPAM
IP: 213.211.51.–
oxidián0
Grafoman
3. 5. 2018   #3
-
0
-

TForm1.allBigger1.

[Error] testy.pas(235): Method identifier expected

???

Nahlásit jako SPAM
IP: 78.102.61.–
Sniper
~ Anonymní uživatel
215 příspěvků
3. 5. 2018   #4
-
0
-

Nu, allBigger1 je objekt, kompiler tedy očekává, že když už sis ho vyžádal, tak s ním něco budeš dělat (volat metodu nebo přistupovat k vlastnostem).

Nahlásit jako SPAM
IP: 92.240.176.–
oxidián0
Grafoman
3. 5. 2018   #5
-
0
-

Celé je to takto:

if TForm1.allBigger1.checked then writeln(f,'[allBigger]');


A v předchozím přízpěvku jsem to zkrátil proto, abych ukázal na místo v kódu kde to hlásí chybu. Takže nechápu v čem je problém.

Nahlásit jako SPAM
IP: 78.102.61.–
Sniper
~ Anonymní uživatel
215 příspěvků
3. 5. 2018   #6
-
+1
-
Zajímavé

Příště to nezkracuj.
Ale chyba je i u mě, to přiznávám - nevšiml jsem si totiž dost důležitý věci. Ty nevoláš objekt ale třídu! TForm1 není objekt, je to třída - změň to na Form1 (nebo jak se ten form jmenuje).

Nahlásit jako SPAM
IP: 92.240.176.–
gna
~ Anonymní uživatel
1891 příspěvků
3. 5. 2018   #7
-
0
-

Kolikrát jsi psal něco := Třída.Create?

Chceš Form1, ne TForm1.

Nahlásit jako SPAM
IP: 213.211.51.–
oxidián0
Grafoman
4. 5. 2018   #8
-
0
-

Díky. Toto jsem opravil. Další chyba:

unit Uc_heb1;

interface

uses
  WinTypes, WinProcs, Messages, ExtCtrls, Dialogs,
  StdCtrls, Controls, Graphics, Gauges, Classes,
  Forms, Menus, SysUtils,
  Uc_obr2,vyslheb, jmeno, book, Buttons,
  uspech,testfnt, Napoveda,antiwin,otviram,
  functions, konstanty,  FileCtrl, Testy;



Mi píše [Fatal Error] Circular unit reference to 'Uc_heb1'

V testy.pas mám

unit Testy;

interface

uses
  Uc_heb1,

V tom prvním unitu chci volat metodu z toho druhého unitu. Ale druhý unit používá první unit, jak jsem psal.

Jak vzniklou situaci vyřešit?

Nahlásit jako SPAM
IP: 78.102.61.–
mjseven0
Návštěvník
4. 5. 2018   #9
-
+1
-
Zajímavé

#8 oxidián
V  Testy.pas přesuň Uc_heb1 z Uses v sekci Interface do Uses v sekci Implementation.

 

Nahlásit jako SPAM
IP: 80.188.191.–
oxidián0
Grafoman
4. 5. 2018   #10
-
0
-

#9 mjseven
Tak tomu tedy říkám zázrak, že je to tak jednoduché. Díky

Nahlásit jako SPAM
IP: 78.102.61.–
MilanL+1
Grafoman
4. 5. 2018   #11
-
0
-

#10 oxidián

pokud používáš nějaké hodnoty napříč vnořenými formuláři máš 2 možnosti:

1) bud jak ti poradili nadřazený do uses v Implementaci 

nebo

2) vytvoření třídy s  hodnotami bez formulářů v uses, tam vytvořit instanci a pak to vložit do uses všech tříd

Nahlásit jako SPAM
IP: 91.139.9.–
oxidián0
Grafoman
4. 5. 2018   #12
-
0
-

Teď řeším problém v tom Uc_heb1

Chci volat veřejnou metodu z TTesty:

Testy.readINI; // step 1.
Testy.JazykyInitiate;        // step 2.
Testy.DynMenu;        // step 3.

[Error] UC_HEB1.PAS(541): Undeclared identifier: 'readINI'

[Error] UC_HEB1.PAS(541): Undeclared identifier: 'readINI'

[Error] UC_HEB1.PAS(543): Undeclared identifier: 'DynMenu'

Ty Testy jsou jako globální proměnná ne? Nerozumím tomu proč nevidí ty metody.

Aktuální verze s chybou je zde:

https://sourceforge.net/projects/uc-heb/files/developer_backups/2018/unfinished/ucheb.240.zip/download

Nahlásit jako SPAM
IP: 78.102.61.–
MilanL+1
Grafoman
4. 5. 2018   #13
-
0
-

   

'třída s hodnotami
unit NastaveniTestu;
interface

uses  ...základní třídy Delphi, které budeš potřebovat

type TNastaveni=class(TObject)     'TObject jako příklad
protected nebo private podle úrovně přístupu
   iHodnota1, iHodnota2 : integer;
   bStav1, bStav2 : boolean;
   function getHodnota : integer;	'getter a setter pro Hodnota2
   procedure setHodnota(value : integer); 
public
   property Hodnota1 : integer read iHodnota1 write iHodnota1;	'přímý přístup
   property Hodnota2 : integer read getHodnota write setHodnota;  'getter/setter , lze integrovat ošetření hodnot na vstupu/výstupu
..
end;

var
   Nastaveni : TNastaveni;

implementation

procedure TNastaveni.setHodnota(value : integer);
begin
   'možno vložit ošetření vstupu, např. omezení rozsahu hodnot
   'proceduru možno též přetížit pro vstupy jiných typů a tam udělat konverzi
   iHodnota2 := value;
end;

function TNastaveni.getHodnota : integer;
begin
   result := iHodnota2;
end;
'ostatní části programu (třídy, formuláře)

interface

uses .., NastaveniTestu, ..

implementation

procedura xxx;
var
   x : integer;
begin
   x := Nastaveni.Hodnota;
   Nastaveni.Hodnota := 22;
   'to samé pro Hodnota2 - compiller si s tím poradí.
end;

podle četnosti používání možná ten název instance "Nastaveni" zkrátit např "NT" jako nastavení testu, nebo "ParT" parametry testu, aby to bylo kratší, ale též, aby bylo poznat o co jde.

Nahlásit jako SPAM
IP: 91.139.9.–
MilanL+1
Grafoman
4. 5. 2018   #14
-
0
-

#12 oxidián
Testy jsou název unity,

není tam vytvořená instance

musíš tam mít v sekci interface ještě

var

    Testy : TTesty;

ale myslím že se to nesmí jmenovat stejně jako unita tzn jeden název změnit

Nahlásit jako SPAM
IP: 91.139.9.–
oxidián0
Grafoman
4. 5. 2018   #15
-
0
-

V kterém souboru?

Takže to mám vložit před

end.

?

Nahlásit jako SPAM
IP: 78.102.61.–
MilanL+1
Grafoman
4. 5. 2018   #16
-
0
-

#15 oxidián
máš tam proměnný, tak instance musí být vytvořena, aby program věděl, kde a jak je to uloženo.

Nahlásit jako SPAM
IP: 91.139.9.–
MilanL+1
Grafoman
4. 5. 2018   #17
-
0
-

#15 oxidián

    procedure upravmenu;
  end;

var

   Testy : TTesty;

implementation

uses
  Uc_heb1;

Nahlásit jako SPAM
IP: 91.139.9.–
oxidián0
Grafoman
4. 5. 2018   #18
-
0
-

do souboru testy.pas?

var TestyOrganizer: TTesty;

end.


TestyOrganizer.readINI; // step 1.


Neznámý identifikátor TestyOrganizer

Nahlásit jako SPAM
IP: 78.102.61.–
oxidián0
Grafoman
4. 5. 2018   #19
-
0
-

OK, dík, zkompilováno to je. Teď se to pokusím rozjet.

Nahlásit jako SPAM
IP: 78.102.61.–
MilanL+1
Grafoman
4. 5. 2018   #20
-
0
-

#19 oxidián
takhle jak to je to může být přístupně všude, jako stejný objekt. pokud bys to chtěl jen jako součást 1 nadřazeného formuláře, tak si tu instanci můžeš vytvořit tam.

Rozdíl je v trvání objektu pokud je to takto, objekt bude v paměti po celou dobu běhu programu a pokud unitu vložíš do uses více Formulářů je objekt společný pro všechny, tzn všichni vidí stejné údaje.

EDIT:

Pokud bys to chtěl pro každý formulář s jiným obsahem, musíš si to vytvořit místně tam, kde to používáš, tzn mohl jsi to mít na stejném místě i v Uc_Heb1.

Pokud bys to chtěl dočastně, tak možno jako třídní proměnou formuláře/třídy a pak přes konstruktor Testy.Create vytvořit a po skončení uvolnit Testy.Free. Možno vytvořit v tý třídě vlastní konstruktor s inicializací hodnot a destruktor.

Nahlásit jako SPAM
IP: 91.139.9.–
oxidián0
Grafoman
4. 5. 2018   #21
-
0
-

Další problém který mám je s proměnnou dir.

unit Testy;
...

type
  TTesty = class(TForm)

  public
    dir : string;


...

end;

implementation

uses
  Uc_heb1;

constructor TTesty.Create;
begin
  dir := extractfilepath(paramstr(0));
end;



Když se zavolá konstruktor tak dir se nenastaví (zdá se).

procedure TTesty.readINI;
var line: String;
    f:textfile;
    i, c, size: integer;
    TestFolderInfo: TStrings;
begin
  if not fileexists(dir+'uc_heb.ini') then exit;


Na poslední řádek zarážku a kukátko na dir a není nastaveno. Jde o to zjistit a nastavit pracovní adresář. Když dir není nastaveno tak program spadne

Nahlásit jako SPAM
IP: 78.102.61.–
MilanL+1
Grafoman
4. 5. 2018   #22
-
0
-

#21 oxidián
dir := extractfilepath(paramstr(0)); 

co je paramstr ? 

pokud to máš podle mě, tak konstruktor nepotřebuješ objekt se vytvoří v základním stavu, tu cestu potřebuješ odněkud získat bud jako vstupní parametr procedury nebo ho vytáhnout z cesty aplikace.

Nahlásit jako SPAM
IP: 91.139.9.–
MilanL+1
Grafoman
4. 5. 2018   #23
-
0
-

podle mě by ini mělo být v adresáři s programem, takže by tam mělo být

dir := ExtractFilePath(Application.ExeName);

Nahlásit jako SPAM
IP: 91.139.9.–
oxidián0
Grafoman
4. 5. 2018   #24
-
0
-

proceduru na načítání ini jsem přesunul do testů, protože během toho načítání ini vytahuji informace o jazycích ze souboru ini. Je tam na to dlouhá smyčka:

  c := maxTestItems-1;
  if (line='[TestyFolders]') and (testyDirFound=true) then
    begin
    TestFolderInfo := TStringList.Create;
    for i:=0 to maxTestFolders-1 do
      begin;
        readln(f,line);
        TestFolderInfo.clear;
        try
          // ExtractStrings([';'],[],PChar(Str),Line)
          ExtractStrings([';'],[],PChar(line), TestFolderInfo);
          if (line='') or ( (line[1]='0') and (trim(line)='0;' ) ) then
            begin
              SubMenuItemsLoaded[i] := false;
              JazykyFolders[i] := '';
              JazykySelected[i] := '';
              continue;
            end;
{
JazykyIndexy - byly iniciovány v
JazykyInitiate. Seznam obsahuje jen prázdné řetězce.
}

          begin
             if (TestFolderInfo.Strings[0][1] = '[') or
             ( length(trim(TestFolderInfo.Strings[0])) = 0 ) then
               break; // ukončit smyčku přidávání jazyků

             Jazyky[i] := TestFolderInfo.Strings[0];

             SubMenuItemsLoaded[i] := true;
             JazykyFolders[i] := TestFolderInfo.Strings[0];
             if not (DirectoryExists(TestyDir+'\'+JazykyFolders[i])) then
                begin
                   CreateDir(TestyDir+'\'+JazykyFolders[i]);
                   showmessage(TestyDir);
                   showmessage('Adresář jsem zkusil vytvořit automaticky: '+TestyDir+'\'+JazykyFolders[i]);
                   ; JazykyFolders[i] := '';
                   SubMenuItemsLoaded[i] := false;
                end
             else
              try
                c := c-1; // potvrdit, že složka s jazykem byla asociována
// Jazyky sub-folder folder specification
// nemá být číslo, ale název adresáře

                if TestFolderInfo.count>2 then
                  JazykySelected[i] :=  TestFolderInfo.Strings[2]
                else
                  JazykySelected[i] := 'textbook';

                if not (DirectoryExists(TestyDir+'\'+JazykyFolders[i]+'\'+JazykySelected[i])) then
                  begin
                    CreateDir(TestyDir+'\'+JazykyFolders[i]+'\'+JazykySelected[i]);
                    showmessage('Adresar ucebnice jsem musel vytvorit: '+TestyDir+'\'+JazykyFolders[i]+'\'+JazykySelected[i]);
                  end;
              finally
              end;
          end;

         SubMenuItemsLoaded[i] := false
        finally
        end;
      end; // end of for ... begin

    lanCount := i+1;
    TestFolderInfo.Free;
    end;


Ve které se nastavují informace o jazycích. Právě proto jsem vytvořil tu třídu Testy, která má všechny tyto informace zawrapovat.

Pak je tam ještě cesta k souboru s testama, velikost fontů, obtížnost testů.

paramstr nevím kde je definováno

Nahlásit jako SPAM
IP: 78.102.61.–
MilanL+1
Grafoman
4. 5. 2018   #25
-
0
-

#24 oxidián
to jo ale někde musíš vzít tu prvotní cestu a napevno by to v dnešní době být nemělo.

Bud vzít tedy cestu k programu nebo pokud jí taháš odjinud jí tam nějak poslat jako parametr.

Např. udělat si v Testy tu proměnou Dir jako property a v Uc_Heb1 jí nastavit Testy.dir := ...

Nahlásit jako SPAM
IP: 91.139.9.–
oxidián0
Grafoman
4. 5. 2018   #26
-
0
-

Unit Testy  

dir := ' ';

Mě ten pokus o zápis do veřejné proměnné dir typu string krachne s vyjímkou Class EAccessViolation with message Access violation at Adress ... in modul UC_HEB2.exe  Write adress ... process stoped

https://sourceforge.net/projects/uc-heb/files/developer_backups/2018/unfinished/?upload_just_completed=true

verze 2401

Nahlásit jako SPAM
IP: 78.102.61.–
gna
~ Anonymní uživatel
1891 příspěvků
4. 5. 2018   #27
-
0
-

Konstruktor nic nedělá, na objekt se nedá dostat...

Tu proměnnou máš inicializovanou, že?

Nahlásit jako SPAM
IP: 213.211.51.–
oxidián0
Grafoman
4. 5. 2018   #28
-
0
-

Konstruktor jsem odstranil.

dir není inicializovaný, jen se snažím přiřadit dir := ' '; uvnitř té funkce readINI

Nahlásit jako SPAM
IP: 78.102.61.–
gna
~ Anonymní uživatel
1891 příspěvků
4. 5. 2018   #29
-
0
-

No a takovou tu drobnost tam máš?

TestyOrganizer := TTesty.Create;
Nahlásit jako SPAM
IP: 213.211.51.–
oxidián0
Grafoman
4. 5. 2018   #30
-
0
-

Ne to tam nemám a kam přesně to mám dát?

Nahlásit jako SPAM
IP: 78.102.61.–
oxidián0
Grafoman
4. 5. 2018   #31
-
0
-

Má to být takto?

TestyOrganizer := TTesty.Create(Form1);
TestyOrganizer.readINI; // step 1.
TestyOrganizer.JazykyInitiate;        // step 2.
TestyOrganizer.DynMenu;        // step 3.


To sice zkompiluje ale taky to krachuje UC_HEB2 raised exception ... Resource TTesty not found

Nahlásit jako SPAM
IP: 78.102.61.–
oxidián0
Grafoman
5. 5. 2018   #32
-
0
-

UC_HEB raised exception ... Resource TTesty not found

Nahlásit jako SPAM
IP: 78.102.130.–
gna
~ Anonymní uživatel
1891 příspěvků
5. 5. 2018   #33
-
0
-

Možná se TForm automaticky pokouší načíst svůj formulář. Toto nevypadá na formulářovou třídu, tak není důvod dědit z TFormu.

TTesty = class(TObject)
Nahlásit jako SPAM
IP: 213.211.51.–
oxidián0
Grafoman
5. 5. 2018   #34
-
0
-

Jen připomínám, že ta třída TTesty má pracovat s menu, které vytváří UC_HEB. Během toho načítání se získají informace o jazycích, a potom pomocí dynmenu vygeneruju menu jazyků. Proto jsem tam předával ten objekt Form1.

Nahlásit jako SPAM
IP: 78.102.130.–
oxidián0
Grafoman
6. 5. 2018   #35
-
0
-

UC_HEB

obsahuje toto:

begin
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Application.CreateForm(TBooksDialog, BooksDialog);
  Application.CreateForm(TFEditace, FEditace);
  Application.CreateForm(TFhledani, Fhledani);
  Application.CreateForm(TOpravduhledani, Opravduhledani);
  Application.CreateForm(TSelectUserDlg, SelectUserDlg);
  Application.CreateForm(TFNapoveda, FNapoveda);
  Application.CreateForm(TNovyfrm, Novyfrm);
  Application.CreateForm(TFOtviram, FOtviram);
  Application.CreateForm(TFtestfont, Ftestfont);
  Application.Run;
end.

Neměl bych tam přidat
Application.CreateForm(TTesty, TestyOrganizer);

?
I když TTesty není formulář.

Nahlásit jako SPAM
IP: 78.102.130.–
MilanL+1
Grafoman
6. 5. 2018   #36
-
0
-

#35 oxidián
ne tam ne.

zkus si v TTesty udělat constructor a v implementaci jen:

constructor TTesty.Create(sender : TObject);
begin
  inherited create;
end;

#32 - nemáš to v uses

podle mě VAR v interface, ten objekt vytvoří hned, nemusíš volat construktor, případně si to můžeš otestovat a ošetšit pomocí assign

Nahlásit jako SPAM
IP: 185.112.167.–
MilanL+1
Grafoman
6. 5. 2018   #37
-
0
-

kdyžtak hod aktuální stav na source mrknu se, ale asi až večer nebo zítra ráno.

Nahlásit jako SPAM
IP: 185.112.167.–
MilanL+1
Grafoman
6. 5. 2018   #38
-
0
-

#35 oxidián
do UC_HEB se mrkni jestli TTesty mas v uses

Nahlásit jako SPAM
IP: 185.112.167.–
gna
~ Anonymní uživatel
1891 příspěvků
Nahlásit jako SPAM
IP: 213.211.51.–
oxidián0
Grafoman
6. 5. 2018   #40
-
0
-

Asi moc nechápu jak to funguje. Protože teď třeba nemohu ten soubor UC_HEB najít. Vidím tam uc_heb1.pas, tak zkusím alespoň dát ten konstruktor do testy.pas.

Tak něco podobného jsem už dříve zkoušel, akorád bez toho parametru sender:

constructor TTesty.Create(sender: TObject);
begin
  inherited create;
end;


A to mi hlásilo myslím stejnou chybu jako teď:

[Error] Testy.pas(61): Not enough actual parameters

Ono to vypadá, že očekává parametr za create. Připomínám že mám Delphi 7, tak nevím jestli to nefunguje jinak než u vás.

verze 2402 - obsahuje ten constucror v testy.pas:

https://sourceforge.net/projects/uc-heb/files/developer_backups/2018/unfinished/ucheb.2402.zip/download

Nahlásit jako SPAM
IP: 78.102.130.–
MilanL+1
Grafoman
7. 5. 2018   #41
-
0
-

#40 oxidián
koukal jsem na tu poslední verzi mělo by to být v pořádku až na to, že Testy máš mimo projekt,

je třeba přídat do projektu: - strom projektu - hlavní položka Uc_Heb - pravý myšítko a vybrat

ADD.. - to otevře file dialog kde vybereš soubor Testy.pas

nebo přes view source a do uses přidat Testy in 'Testy.pas';

případně by to mělo jít i přetažením - Otevřeš projekt  a Testy.pas a přetáhneš Testy do projektu

Když si rozbalíš strom projektu musí být Testy jeho součástí.

Nahlásit jako SPAM
IP: 193.165.115.–
MilanL+1
Grafoman
7. 5. 2018   #42
-
0
-

#41 MilanL
ted jsem si všiml další věci TTesty nejsou TForm ale TObject, tím jak s tím pracuješ si to děsně komplikuješ.

Nahlásit jako SPAM
IP: 193.165.115.–
oxidián0
Grafoman
7. 5. 2018   #43
-
0
-

testy.pas přidáno do projektu.

sender: opraveno na TForm

gna psal: "Toto nevypadá na formulářovou třídu, tak není důvod dědit z TFormu."

constructor TTesty.Create(sender: TForm);
begin
  inherited create;
end;

stále píše

[Error] testy.pas(61): Not enough actual parameters (inherited create)

Jinak když to vykomentuju, tak to zkompilovat jde ale stále je tam ta runtime chyba. Program spustit jde.

A nemá to být spíše takto?

constructor TTesty.Create(sender: TForm);
begin
  inherited create(form1);
end;


To už zkompilovat jde bez problému, ale stále je tam ta stejná runtime error.

Nahlásit jako SPAM
IP: 78.102.130.–
MilanL+1
Grafoman
7. 5. 2018   #44
-
0
-

#43 oxidián

gna psal: "Toto nevypadá na formulářovou třídu, tak není důvod dědit z TFormu."

Myšleno TTesty = class(TForm) - tam by podle nás měl být (TObject)

pokud to necháš na TForm měl by parametr sender v create být TComponent.

mě to háže nějakou chybu ještě před začátkěm aniž by se to někam dostalo :(

ale mám nový delphi, tak to může být tím

Nahlásit jako SPAM
IP: 193.165.115.–
MilanL+1
Grafoman
7. 5. 2018   #45
-
0
-

#44 MilanL
menší doplněk

if not assigned(TestyOrganizer) then TestyOrganizer := TTesty.Create(Form1);
TestyOrganizer.readINI; // step 1.                          hlásí soubor ini bez textu
TestyOrganizer.JazykyInitiate;        // step 2.         háže chybu - asi není nic načteno
TestyOrganizer.DynMenu;        // step 3.

při ukončování hlásí chybu při pokusu o uložení stavu

Nahlásit jako SPAM
IP: 193.165.115.–
MilanL+1
Grafoman
7. 5. 2018   #46
-
0
-

#45 MilanL
další 2 věci

TTesty.JazykyInitiate

v řádce která přidává položku menu by mělo být

Form1.Testy.add.....

a když už tam máš proměnou lanCount tak jí pouzívej místo MaxItems, jinak tam budeš mít prázdný řádky v menu.

v další funkci bys měl ošetřit Jazyky[i] s prázdnou hodnotou.

Nahlásit jako SPAM
IP: 193.165.115.–
oxidián0
Grafoman
7. 5. 2018   #47
-
0
-

   

constructor TTesty.Create(sender: TObject);
begin
  inherited create();
end;


Mě to teď háže tuto chybu:

curFile := FindComponent('file'+IntToStr(i*10 + 1)) as TMenuItem;


[Error] testy.pas(78): Undeclared identifier: 'FindComponent'

Zbytek chyb musím odladit. Jde o to, že jsem tu třídu teprve vytvořil a tted ji musim rozjet a otestovat.

Nahlásit jako SPAM
IP: 78.102.130.–
oxidián0
Grafoman
7. 5. 2018   #48
-
0
-

#46 MilanL
Jo, právě k tomu jsem tu proměnnou zavedl, abych to opravil.

Nahlásit jako SPAM
IP: 78.102.130.–
MilanL+1
Grafoman
7. 5. 2018   #49
-
0
-

chtělo by to spíš nějakýho kecálka než formum, píšu ti každou věc do nový odpovědi a narůstáto tu.

jinak nemusel bys v implementaci mít to uses uc-heb, kvůli tomu menu, stačilo by předávat proceduře menuItem, kam se to má vložit.

Nahlásit jako SPAM
IP: 193.165.115.–
MilanL+1
Grafoman
7. 5. 2018   #50
-
0
-

#48 oxidián
form1.findcomponent

Nahlásit jako SPAM
IP: 193.165.115.–
oxidián0
Grafoman
7. 5. 2018   #51
-
0
-

Tak toto jsem v testy.pas vyrušil:

//    Nic: TMenuItem;
//    N1: TMenuItem;
//    Testy: TMenuItem;
//    okruhy1: TMenuItem;


A odkazuji na TMenuItem. Program mi najíždí, ale stále runtime error. Menu testy jsem ještě nerozjel. Budu nad tím ještě dumat.

Nahlásit jako SPAM
IP: 78.102.130.–
oxidián0
Grafoman
7. 5. 2018   #52
-
0
-

Ted řeším cestu dir.

dir:=extractfilepath(paramstr(0));


ve form1 vrací cestu k programu. Mě příjde že v testy.pas

krachují obě varianty:

  dir := extractfilepath(paramstr(0));
  dir := extractfilepath(Application.ExeName);


přičemž nevím co je paramstr

tj. v form1 to funguje, ale v testech to krachne v TTesty.readINI

A díky že jste pomohli, konečně jsem se dostal dále.

Nahlásit jako SPAM
IP: 78.102.130.–
MilanL+1
Grafoman
7. 5. 2018   #53
-
0
-

#52 oxidián
no mě to funguje. tak jak jsi to tam měl v tý poznámce.

zkus si dát do watch dir i Application.exename

případně si tu cestu vytáhni ve form1 a do těch funkcí s INI v testy jí pošli parametrem.

Jakou máš verzi D7 start zdarma nebo nějakou vyšší profesional, enterprise?

Zauvažoval bych nad přechodem na nový Delphi 10.x město, mám 10.1 Berlin a funguje mi to jsou tam třeba jen 2 úpravy v antiWIn

Nahlásit jako SPAM
IP: 193.165.115.–
MilanL+1
Grafoman
7. 5. 2018   #54
-
0
-

#52 oxidián
paramstr - jsou parametry příkazové řádky, to ted nepoužíváš, když to se používá při spouštění stylem

"program něco něco-dalšího"

Nahlásit jako SPAM
IP: 193.165.115.–
oxidián0
Grafoman
7. 5. 2018   #55
-
0
-

#53 MilanL
verze delphi zdarma. nechci se zabývat vývojem aplikace profesionálně, jde mi jen o nutnou úpravu, aby se mi jednodušeji a efektivněji učili slovíčka

Nahlásit jako SPAM
IP: 78.102.130.–
oxidián0
Grafoman
7. 5. 2018   #56
-
0
-

Application.ExeName ukazuje na aplikaci, to je OK.

Jaj, já zapomněl. Já si teď vzpomněl proč jsem tam měl dir := " "; protože do toho dir, nejde zapisovat. To jsem psal v jiném vláknu kde jsem se na to ptal, proč do dir nemohu nic zapsat. Ono to vypadá, že není schopen si zapamatovat tu hodnotu (předpokládám - jakoukoliv hodnotu, nejen u toho dir).

Nahlásit jako SPAM
IP: 78.102.130.–
MilanL+1
Grafoman
7. 5. 2018   #57
-
0
-

#56 oxidián
vložil jsi tam tu podmínku na existenci objektu a create pokud neexistuje? jaj ksem psal v #45

Nahlásit jako SPAM
IP: 193.165.115.–
MilanL+1
Grafoman
7. 5. 2018   #58
-
0
-

#57 MilanL
nepamatuje nebo hodí chybu access violation ... write of? = #45 rešením je ta podmínka
"if not assigned(TestyOrganizer) then TestyOrganizer := TTesty.Create(Form1);"

v 1 řádce

se na to koukni, udělej zarážku v Uc_heb1 na řádce, kde voláš read ini a přes watch koukni na objekt "TestyOrganizer"

Nahlásit jako SPAM
IP: 193.165.115.–
MilanL+1
Grafoman
7. 5. 2018   #59
-
0
-

#58 MilanL
byla tam chyba v assignet měl jsem tam název třídy a ne instance opraveno

Nahlásit jako SPAM
IP: 193.165.115.–
oxidián0
Grafoman
7. 5. 2018   #60
-
0
-

Nevím proč jsem to neudělal. Myslel jsem že jsem to už udělal. Teď jsem hledal kde mám ten řádek

TestyOrganizer := ... a zjistil jsem že tam mám

// TestyOrganizer := TTesty.Create(Form1);

Uff, tak já teď vůbec nevím proč jsem to zakomentoval. To jsem neměl.

Nahlásit jako SPAM
IP: 78.102.130.–
oxidián0
Grafoman
7. 5. 2018   #61
-
0
-
Nahlásit jako SPAM
IP: 78.102.130.–
MilanL+1
Grafoman
7. 5. 2018   #62
-
0
-

#61 oxidián
ty sis zrušil v Uc_Heb1, ty menu itemy Testy a Okruhy a v souboru Testy sis to zapoznámkoval.

na jednom místě ten vstupní bod menu musíš nechat, pokud ho uděláš v tom souboru Testy, musíš to pak provázat do Menu Formuláře.

EDIT: 

A pak podle umístění přidávat ty položky bud do

Testy.add   .  nebo . . Form.Testy.add

u okruhu to samé.

Nahlásit jako SPAM
IP: 193.165.115.–
oxidián0
Grafoman
7. 5. 2018   #63
-
0
-

#62 MilanL
Já jsem je přesunul do veřejné sekce v Uc_heb1, abych se k nim mohl dostat z Testů readINI, writeINI.

Nahlásit jako SPAM
IP: 78.102.130.–
MilanL+1
Grafoman
7. 5. 2018   #64
-
+1
-
Zajímavé

#63 oxidián
patří tam, kde byli, prvky formuláře jsou obecně veřejné.

a inicializují se při otevření formuláře, prvky v Public nejsou inicializované - musel bys je inicializovat programově před INI.

Nahlásit jako SPAM
IP: 193.165.115.–
oxidián0
Grafoman
7. 5. 2018   #65
-
0
-

Opravím. Ještě dotaz:

form1.Testy: nil znamená co?

Po té co jsem to opravil už ten řádek projel:

form1.Testy.Add(langMenuItems[i]); // pøidat menu
Nahlásit jako SPAM
IP: 78.102.130.–
oxidián0
Grafoman
7. 5. 2018   #66
-
0
-

Konečně jsem to spustil bez té chyby runtime. Už i menu je vygenerované.

Nahlásit jako SPAM
IP: 78.102.130.–
MilanL+1
Grafoman
7. 5. 2018   #67
-
0
-

#66 oxidián
nil znamená prázdný nevytvořený objekt.

kdyžje vytvořený tak tym vždy něco je v závorkách, např u TestyOrganizer kdybys kouknul v Uc-heb1 bys viděl (0,(...,... jsou to bud hodnoty nebo adresy proměnných.

Nahlásit jako SPAM
IP: 193.165.115.–
oxidián0
Grafoman
7. 5. 2018   #68
-
0
-

dotaz:

když během readINI z Testy.pas volám funkci

SubDirs := createSubDirsList(TestyDir, TestyDirs[i], SubMenuItemsLoaded);

a v té funkci mám kód:

// Create list of subfolders (Testy/*/*)
function createSubDirsList(TestyDir: string; subdir: string; SubMenuItemsLoaded : Array of boolean):TStringList;
var i: Integer;
  SubDirs : TStringList; // for folders sreach
  SearchRecord : TSearchRec;
begin
  SubDirs := TStringList.create();
  for i:=0 to maxSubFolders-1 do
    begin;
      if SubMenuItemsLoaded[i]=true then
        continue;
      SubDirs.clear;
      if FindFirst(TestyDir+'/'+subdir+'/*', faDirectory, SearchRecord) = 0 then
        begin
          repeat
            if (SearchRecord.attr=faDirectory)  and
               (SearchRecord.name[1]<>'.') then
            SubDirs.add(SearchRecord.Name);
          until FindNext(SearchRecord)<>0;
          SysUtils.FindClose(SearchRecord);
        end;

       // submenuItems[i].name := TestFolderInfo[0];
    SubMenuItemsLoaded[i] := true;
    end; // end of for ... begin
  Result := SubDirs;
// SubDirs.free;
end;


kde používám

SubMenuItemsLoaded[i] := true;


ponechme stranou, že bych to měl nejspíš přesunout jako proceduru do testy.pas - jak bych k tomu měl přistupovat? Když to volám zevnitř třídy? Jako TTesty.SubMenuItemsLoaded[i] := true
?

Zvažuju to přesunutí, ono to dělá skoro to samé jako createTestyDirsList, tam se ale vrací jen řetězec a nenastavuje se žádná vlastnost či proměnná třídy.

Nahlásit jako SPAM
IP: 78.102.130.–
gna
~ Anonymní uživatel
1891 příspěvků
7. 5. 2018   #69
-
0
-

Identifikátory se "hledají" z aktuální úrovně do vyšších.

Pokud tady chceš používat stejně pojmenovaný parametr i vlastnost objektu (nejsem si jistý, jestli to vůbec jde), tak přednostně to bude parametr a vlastnost musíš napsat jako Self.vlastnost. Pokud kolize není, tak rozlišovat nemusíš. Když se podíváš na konvence pojmenovávání, tak ke kolizím ani nedochází.

Pusť konečně z hlavy pokusy používat název třídy jinak než při určování typu nebo vytváření instance.

Nahlásit jako SPAM
IP: 213.211.51.–
MilanL+1
Grafoman
8. 5. 2018   #70
-
0
-

#69 gna
on to předává funkci v parametrech

#68 oxidián
máš to jako vstupní pole, takže přistupovat přímo, jen bych tam možná vložil const nebo var


createSubDirsList(TestyDir: string; subdir: string; var SubMenuItemsLoaded : Array of boolean):TStringList;

jen si myslím že to tam vůbec nepatří.

zamysli se nad tím jaká je vazba mezi polem se subdir a submenuitems,

Nahlásit jako SPAM
IP: 193.165.115.–
MilanL+1
Grafoman
8. 5. 2018   #71
-
0
-


jinak jak psal gna, když použiješ u funkce třídy pro lokální proměnou stejný název jako má proměnná třídy tak se pro lokální použije jen název a pro proměnnou třídy použije self.proměná.

tu funkci načtení subdir do TstringList, bych udělal univerzální

Nahlásit jako SPAM
IP: 193.165.115.–
MilanL+1
Grafoman
8. 5. 2018   #72
-
0
-

#68 oxidián
mimochodem, kam se poděl ten způsob z lonska, kdy jsme vyřešili a měl jsi hotový to generování menu pro jazyky a testy z adresářové struktury?

Nahlásit jako SPAM
IP: 193.165.115.–
oxidián0
Grafoman
8. 5. 2018   #73
-
0
-

Pokouším se to přesunout do Testy.


 

// Create list of subfolders (Testy/*/*)
function createSubDirsList(subdir: string):TStringList;
var i: Integer;
  SubDirs : TStringList; // for folders sreach
  SearchRecord : TSearchRec;
begin
  SubDirs := TStringList.create();
  for i:=0 to maxSubFolders-1 do
    begin;
      if Self.SubMenuItemsLoaded[i]=true then
        continue;
      SubDirs.clear;
      if FindFirst(TestyDir+'/'+subdir+'/*', faDirectory, SearchRecord) = 0 then
        begin
          repeat
            if (SearchRecord.attr=faDirectory)  and
               (SearchRecord.name[1]<>'.') then
            SubDirs.add(SearchRecord.Name);
          until FindNext(SearchRecord)<>0;
          SysUtils.FindClose(SearchRecord);
        end;

       // submenuItems[i].name := TestFolderInfo[0];
    Self.SubMenuItemsLoaded[i] := true;
    end; // end of for ... begin
  Result := SubDirs;
// SubDirs.free;
end;

Smazal jsem ty dva argumenty a nechal jen jeden. Teď ale nemohu přijít na to jak se dostat k
TTesty.SubMenuItemsLoaded
 

Self is not declared.

Nahlásit jako SPAM
IP: 78.102.130.–
oxidián0
Grafoman
8. 5. 2018   #74
-
0
-

#72 MilanL
Kam se poděl... Nevím už v jakém to bylo vlákně, nevím jakou to mělo formu.

submenuitems - mělo by sloužit k tomu účelu, aby se mohly načíst okruhy. Ty se nemohou načíst dřív, dokud nejsou načtené jazyky. Okruhy se načtou až poté, co načtu informaci o tom, která učebnice je vybrána; pokud žádný učebnice není vybrána, tedy ani žádný jazyk; pak položky okruhy nebudou vygenerováné.

Struktura adresářů by měla být:

Testy/Jazyk/Učebnice/Okruh/*.*

Nahlásit jako SPAM
IP: 78.102.130.–
oxidián0
Grafoman
8. 5. 2018   #75
-
0
-
Nahlásit jako SPAM
IP: 78.102.130.–
MilanL+1
Grafoman
9. 5. 2018   #76
-
0
-

#73 oxidián
tu funkci ted máš mimo třídu, měl bys ji bud dát do třídy a budeš mít přímý přístup, nebo přes TestyOrganizer. ale to bys musel mít to pole public.

Nahlásit jako SPAM
IP: 91.139.9.–
oxidián0
Grafoman
9. 5. 2018   #77
-
0
-

Takže jsem tam měl dát function TTesty.createSubDirsList, teď už mi to jede .dík

Nahlásit jako SPAM
IP: 78.102.130.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 4 hosté

Podobná vlákna

Tridy — založil Gadael

Tridy — založil Omfg

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý