Page 1 of 2 1 2 LastLast
Results 1 to 15 of 21

Thread: Applicatie in meerdere talen

  1. #1

    Applicatie in meerdere talen

    Wil je een applicatie in meerdere talen schrijven?

    Hier een tip om niet alles in de source te hoeven aanpassen:

    Voorbeeld:
    Zet tussen de Uses en Type het volgende:
    --------------------
    resourcestring
    Test1 = 'Wat je allemaal niet kunt doen in Delphi!';
    Test2 = 'Delphi is een Rapid Development Tool';
    Test3 = 'Delphi 6.0 is de opvolger van Delphi 5.0';
    Test4 = 'NlDelphi is een mooie website';
    --------------------

    Als je nu een string-waarde ergens in moet plaatsen kun je dit nu doen met de resourcestring:

    Voorbeeld(1):
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    ShowMessage(Test1);
    end;

    Voorbeeld(2):
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    Memo1.Lines.Add(Test2);
    end;

    Bij deze 2 voorbeelden komt als resultaat dus wat je heb ingevoerd bij de resourcestring. Als je een grote applicatie schrijft, en je wilt deze in verschillende talen maken, is het simpel om gewoon even de tekst in een andere taal om te zetten
    Dus: test4 : 'NlDelphi is a beautiful website'; En je hoeft verder in je applicatie niets meer te veranderen.


    Groeten Joost

  2. #2
    Senior Member walterheck's Avatar
    Join Date
    Oct 2001
    Location
    Belo Horizonte, Brasil
    Posts
    4,212
    of als je het helemaal goed wilt doen, moet je eens kijken naar resource dlls.
    dit zijn dll's die je maakt voor iedere taal waar je de applicatie naar gaat porten en dan gebruik je dus voor iedere taal een andere dll. dit begrip heet internationalization and localization. je kunt er een hoop over terug vinden in de help van delphi. zoek gewoon ff op : "creating international applications" en je vindt het complete hoofdstuk terug.


    hier kun je ook een hoop terug vinden over internationalization.

  3. #3

    Thumbs up

    Hoi Joost,

    'NlDelphi is een mooie website'
    Dank je! Ook voor de goede tip natuurlijk
    Marcel

  4. #4
    notice-itter SvG's Avatar
    Join Date
    Apr 2002
    Location
    's-Hertogenbosch
    Posts
    4,865
    Deze code heb ik zelf ooit een keer geschreven voor de lol:

    Delphi Code:
    1. Tlanguage = record
    2.     Component_count: Byte;
    3.     Components: array [1..100] of Tcompo;
    4.  
    5.     Text_count: Byte;
    6.     Text: array [1..100] of Ttext;
    7.  
    8.     Language_Name: String;
    9.  end;
    10.  
    11. Const
    12.          LNF_COMPONENT_NR = 1;
    13.          LNF_TEXT_NR      = 2;
    14.          LNF_COMPONENT_STR= 'COMP';
    15.          LNF_TEXT_STR     = 'TXT';
    16.  
    17.  
    18. Procedure LoadLNFfile(filename: String);
    19. Function  Updatecomponents(Mainform: Tform;
    20.                           New_language: String = ''): Boolean;
    21. Function  Gettext(Name: String): String;
    22. Procedure Set_current_languagenumber(Language: String);
    23.  
    24.  
    25.  
    26. Function Gettext(Name: String): String;
    27. Var
    28.  I: byte;
    29. begin
    30.    For I := 1 to High(Languages[Current_language].text) do
    31.     If Languages[Current_language].text[I].text_name = Name then
    32.      begin
    33.        Result := Languages[Current_language].text[I].Text;
    34.        Exit;
    35.      end;
    36. end;
    37.  
    38. Procedure Set_current_languagenumber(Language: String);
    39. begin
    40.    Current_language := Getlangnumber(Language);
    41. end;
    42.  
    43. Function GetLangNumber(Str: String): Byte;
    44. Var
    45.  I: Byte;
    46. begin
    47. Result := Current_language;
    48.    For I := 1 to High(Languages) do
    49.     If Compare_strings(Languages[I].Language_Name, Str, False) then
    50.      Result := I;
    51. If Result <> Current_language then
    52.  Exit;
    53.     For I := 1 to High(Languages) do
    54.      If Languages[I].Language_Name = '' then
    55.       begin
    56.         Result := I;
    57.         Exit;
    58.       end;
    59.  
    60. end;
    61.  
    62. Function Updatecomponents(Mainform: Tform;
    63.                           New_language: String = ''): Boolean;
    64. Var
    65.  S, Capt: String;
    66.  Lan_nr, I: Word;
    67.  Contrl: Tcomponent;
    68. begin
    69.   S := New_language;
    70.   Lan_nr := Getlangnumber(Trim(S));
    71.  
    72.   If Languages[Lan_nr].Component_count > 0 then
    73.   For I := 1 to Languages[Lan_nr].Component_count do
    74.    begin
    75.      S := Languages[Lan_nr].Components[I].Component_name;
    76.      Capt := Languages[Lan_nr].Components[I].Caption;
    77.      Contrl := Mainform.Findcomponent(S);
    78.      If Contrl is Tbutton then
    79.         (contrl as Tbutton).Caption := Capt;
    80.    end;
    81.  
    82. end;
    83.  
    84. Procedure LoadLNFfile(Filename: String);
    85. Var
    86.  F: Textfile;
    87.  S: String;
    88.  Words: Array of String;
    89.  I: Byte;
    90.  Comp_count: Byte;
    91.  LAN_NR: Byte;
    92.  Lanname: String;
    93.  Typ: Cardinal;
    94. Begin
    95.    Assignfile(F, Filename);
    96.    Reset(F);
    97.  
    98.      For I := 1 to High(Languages) do
    99.    begin
    100.      Languages[I].Component_count := 0;
    101.      Languages[I].Text_count := 0;
    102.      Languages[I].Language_Name := '';
    103.    end;
    104.  
    105.    Comp_count := 0;
    106.      Repeat
    107.       Readln(F, S);
    108.       replacetext(S, ' ', '#');
    109.       Replacetext(S, ';', ' ');
    110.       Setlength(Words, Count_words(S));
    111.       String_into_pieces(S, Words);
    112.       For I := 0 to High(Words) do
    113.        Replacetext(Words[I], '#', ' ');
    114.  
    115.        If Words[0][1] + Words[0][2] = '//' then
    116.         Continue;
    117.  
    118.        If Words[0][1] = '[' then
    119.         begin
    120.           lanname := Copy(Words[0], 2, Pos(Words[0], ']')-2);
    121.           Lan_nr := Getlangnumber(Lanname);
    122.           Languages[Lan_nr].Language_Name := Lanname;
    123.           Languages[Lan_nr].Component_count := 1;
    124.           Continue;
    125.         end;
    126.  
    127.         If Words[1] = LNF_COMPONENT_STR then
    128.           Typ := LNF_COMPONENT_NR;
    129.         If Words[1] = LNF_TEXT_STR then
    130.           Typ := LNF_TEXT_NR;
    131.  
    132.         Case Typ of
    133.          LNF_COMPONENT_NR: Begin
    134.             Inc(Languages[Lan_nr].Component_count);
    135.             Languages[Lan_nr].Components[Languages[Lan_nr].Component_count].Component_name := Words[0];
    136.             Languages[Lan_nr].Components[Languages[Lan_nr].Component_count].Caption := Words[2];
    137.                           End;
    138.          LNF_TEXT_NR:    Begin
    139.             Inc(Languages[Lan_nr].text_count);
    140.             Languages[Lan_nr].text[Languages[Lan_nr].text_count].Text_name := Words[0];
    141.             Languages[Lan_nr].text[Languages[Lan_nr].text_count].Text := Words[2];
    142.                           End;
    143.         end;
    144.      until
    145.       Eof(F);
    146.  
    147.    Closefile(F);
    148.  
    149.    Current_language := 1;
    150. end;
    Maak globaal aan:

    Delphi Code:
    1. Languages: Array [1..10] of TLanguage;
    2.  Current_language: Byte;
    En roep de procedure LoadLNDFfile op.
    Deze laad het bestandje in de Array.

    Door nu Gettext op te roepen met een bijhorende naam ( BV: "T_BTN1") zal deze de de juiste waarde met juiste taal teruggeven. Door Updatecomponents op te roepen zullen alle componenten die zijn ingevoegd in het bestand worden aangepast aan de juiste taal.

    De bestandsopbouw is als volgt:

    [ LAND_NAAM ]

    NAAM;TYPE;WAARDE

    [ LAND_NAAM ]

    NAAM;TYPE;WAARDE

    Einde van document. als je BV een button genaamd Button1 hebt en je wilt 2 talen gebruiken dan doe je:

    [Nederlands]

    button1;COMP;Knop 1

    [Engels]

    button1;COMP;button 1

    en als je een message erbij wilt hebben:

    [Nederlands]

    button1;COMP;Knop 1
    Mess1;TXT;bericht van knopje 1

    [Engels]

    button1;COMP;button 1
    Mess1;TXT;message from button 1

    als je nu een knopje aanmaakt. De juiste code uitvoert zoals hierboven beschreven werd, in het knopje de code:

    showmessage(gettext('Mess1'));

    krijg je het goede berichtje in de juiste taal. Ook heb ik nog in de code toegevoegd dat je een deel van het document kunt negeren, en is dat nou mooier te doen dan met "//". Als de 1e 2 tekens van een regel "//" zijn, word de regel negeerd.

    Laat het even weten als er fouten zijn.
    Last edited by GolezTrol; 08-Dec-08 at 17:45.
    !

  5. #5
    notice-itter SvG's Avatar
    Join Date
    Apr 2002
    Location
    's-Hertogenbosch
    Posts
    4,865
    Sorry, 2 types vergeten te declareren:

    Delphi Code:
    1. Tcompo = record
    2.     Component_name: String;
    3.     Caption: String;
    4.  end;
    5.  
    6.  Ttext = Record
    7.     text_name: String;
    8.     Text: String;
    9.  end;
    Last edited by GolezTrol; 08-Dec-08 at 17:45.
    !

  6. #6
    5th member of nldelphi
    Join Date
    Mar 2001
    Location
    Alkmaar
    Posts
    2,127
    En nu nog even door de Pascal -> vB Code code converter, en iedereen kan
    het makkelijk lezen.

    Richard
    RLD

  7. #7
    Senior Member PsychoMark's Avatar
    Join Date
    Nov 2001
    Location
    Raamsdonksveer
    Posts
    10,269
    ...en dan moet je nog voor alle componenten die functie aanroepen? Handiger lijkt mij een self-contained functie die alle componenten (eventueel alleen diegenen met een bepaalde tag) automatisch wijzigt, beetje leuk RTTI erdoorheen om het globaal te houden en voila...
    Qui custodiet ipsos custodes

  8. #8
    notice-itter SvG's Avatar
    Join Date
    Apr 2002
    Location
    's-Hertogenbosch
    Posts
    4,865
    hoezo moet je ze voor alle componenten apart oproepen. Daar heb ik toch de procedure Updatecomponents voor gebruiken??????

    Code:
    Tlanguage = record 
    Component_count: Byte; 
    Components: array [1..100] of Tcompo; 
    
    Text_count: Byte; 
    Text: array [1..100] of Ttext; 
    
    Language_Name: String; 
    end; 
    
    Const 
    LNF_COMPONENT_NR = 1; 
    LNF_TEXT_NR = 2; 
    LNF_COMPONENT_STR= 'COMP'; 
    LNF_TEXT_STR = 'TXT'; 
    
    
    Procedure LoadLNFfile(filename: String); 
    Function Updatecomponents(Mainform: Tform; 
    New_language: String = ''): Boolean; 
    Function Gettext(Name: String): String; 
    Procedure Set_current_languagenumber(Language: String); 
    
    
    
    Function Gettext(Name: String): String; 
    Var 
    I: byte; 
    begin 
    For I := 1 to High(Languages[Current_language].text) do 
    If Languages[Current_language].text[I].text_name = Name then 
    begin 
    Result := Languages[Current_language].text[I].Text; 
    Exit; 
    end; 
    end; 
    
    Procedure Set_current_languagenumber(Language: String); 
    begin 
    Current_language := Getlangnumber(Language); 
    end; 
    
    Function GetLangNumber(Str: String): Byte; 
    Var 
    I: Byte; 
    begin 
    Result := Current_language; 
    For I := 1 to High(Languages) do 
    If Compare_strings(Languages[I].Language_Name, Str, False) then 
    Result := I; 
    If Result <> Current_language then 
    Exit; 
    For I := 1 to High(Languages) do 
    If Languages[I].Language_Name = '' then 
    begin 
    Result := I; 
    Exit; 
    end; 
    
    end; 
    
    Function Updatecomponents(Mainform: Tform; 
    New_language: String = ''): Boolean; 
    Var 
    S, Capt: String; 
    Lan_nr, I: Word; 
    Contrl: Tcomponent; 
    begin 
    S := New_language; 
    Lan_nr := Getlangnumber(Trim(S)); 
    
    If Languages[Lan_nr].Component_count > 0 then 
    For I := 1 to Languages[Lan_nr].Component_count do 
    begin 
    S := Languages[Lan_nr].Components[I].Component_name; 
    Capt := Languages[Lan_nr].Components[I].Caption; 
    Contrl := Mainform.Findcomponent(S); 
    If Contrl is Tbutton then 
    (contrl as Tbutton).Caption := Capt; 
    end; 
    
    end; 
    
    Procedure LoadLNFfile(Filename: String); 
    Var 
    F: Textfile; 
    S: String; 
    Words: Array of String; 
    I: Byte; 
    Comp_count: Byte; 
    LAN_NR: Byte; 
    Lanname: String; 
    Typ: Cardinal; 
    Begin 
    Assignfile(F, Filename); 
    Reset(F); 
    
    For I := 1 to High(Languages) do 
    begin 
    Languages[I].Component_count := 0; 
    Languages[I].Text_count := 0; 
    Languages[I].Language_Name := ''; 
    end; 
    
    Comp_count := 0; 
    Repeat 
    Readln(F, S); 
    replacetext(S, ' ', '#'); 
    Replacetext(S, ';', ' '); 
    Setlength(Words, Count_words(S)); 
    String_into_pieces(S, Words); 
    For I := 0 to High(Words) do 
    Replacetext(Words[I], '#', ' '); 
    
    If Words[0][1] + Words[0][2] = '//' then 
    Continue; 
    
    If Words[0][1] = '[' then 
    begin 
    lanname := Copy(Words[0], 2, Pos(Words[0], ']')-2); 
    Lan_nr := Getlangnumber(Lanname); 
    Languages[Lan_nr].Language_Name := Lanname; 
    Languages[Lan_nr].Component_count := 1; 
    Continue; 
    end; 
    
    If Words[1] = LNF_COMPONENT_STR then 
    Typ := LNF_COMPONENT_NR; 
    If Words[1] = LNF_TEXT_STR then 
    Typ := LNF_TEXT_NR; 
    
    Case Typ of 
    LNF_COMPONENT_NR: Begin 
    Inc(Languages[Lan_nr].Component_count); 
    Languages[Lan_nr].Components[Languages[Lan_nr].Component_count].Component_name := Words[0]; 
    Languages[Lan_nr].Components[Languages[Lan_nr].Component_count].Caption := Words[2]; 
    End; 
    LNF_TEXT_NR: Begin 
    Inc(Languages[Lan_nr].text_count); 
    Languages[Lan_nr].text[Languages[Lan_nr].text_count].Text_name := Words[0]; 
    Languages[Lan_nr].text[Languages[Lan_nr].text_count].Text := Words[2]; 
    End; 
    end; 
    until 
    Eof(F); 
    
    Closefile(F); 
    
    Current_language := 1; 
    end; 
    
    Maak globaal aan: 
    
    Languages: Array [1..10] of TLanguage; 
    Current_language: Byte;
    !

  9. #9
    Senior Member PsychoMark's Avatar
    Join Date
    Nov 2001
    Location
    Raamsdonksveer
    Posts
    10,269
    Ah, niet gezien in eerste instantie, sorry. Maar goed, dan moet je nog voor elke component-soort dingen gaan toevoegen in de vorm van 'if Contrl is TBla'...
    Qui custodiet ipsos custodes

  10. #10
    notice-itter SvG's Avatar
    Join Date
    Apr 2002
    Location
    's-Hertogenbosch
    Posts
    4,865
    ook daar heeft onze delphi-fanaat aan gedacht. Dit keer een compleet nieuwe code die met een paar simpele procedures en functies een geheel formulier in een andere taal zet:

    Code:
     TLANCOMPO = record
        compname: String[50];
        compprop: String[30];
        value: String[250];
      end;
    
      TLANtext = record
        Textname: String[10];
        textvalue: String[250];
      end;
    
      Tlanguage = Packed record
        Lanname: string[50];
        Components: array [1..50] of TLANCOMPO;
        Texten:    array [1..50] of TLANTEXT;
      end;
    
      TLanchanger = Class(Tobject)
       private
          Lancount, Curlan: Byte;
          Languages: array of Tlanguage;
          Mainform: Tform;
       public
          Function Createnewlanguage(Lanname: String): Byte;
          Procedure Setlanguagename(Lannr: Byte; Lanname: String);
          Procedure Addcomponent(Lannr: Byte; Compname, Compprop, value: String);
          Procedure Addtext(Lannr: Byte; textname, Textvalue: String);
    
          Function Gettext(Textname: String): String;
          Procedure Updatecomponents;
    
          Procedure Loadfromfile(Const Filename: String);
          Procedure Savetofile(Const Filename: String);
    
       end;
    
    procedure TLanchanger.Addcomponent(Lannr: Byte; Compname, Compprop,
      value: String);
    Var
     I, Emptyat: Byte;
     Lan: Tlanguage;
    begin
      Lan := Languages[Lannr];
    
      Emptyat := 0;
      For I := 1 to high(Lan.components) do
       If Trim(Lan.Components[I].compname) = '' then
        begin
           Emptyat := I;
           Break;
        end;
    
      If Emptyat = 0 then Exit;
    
      Lan.Components[emptyat].compname := Compname;
      Lan.Components[emptyat].compprop := Compprop;
      Lan.components[emptyat].value    := Value;
    
      Languages[Lannr] := Lan;
    end;
    
    procedure TLanchanger.Addtext(Lannr: Byte; textname, Textvalue: String);
    Var
     I, Emptyat: Byte;
     Lan: Tlanguage;
    begin
      Lan := Languages[Lannr];
    
      Emptyat := 0;
      For I := 1 to high(Lan.texten) do
       If Trim(Lan.texten[I].Textname) = '' then
        begin
           Emptyat := I;
           Break;
        end;
    
      If Emptyat = 0 then Exit;
    
      Lan.texten[emptyat].textname := textname;
      Lan.texten[emptyat].textvalue := textvalue;
    
      Languages[Lannr] := Lan;
    end;
    
    function TLanchanger.Createnewlanguage(Lanname: String): Byte;
    begin
       Setlength(Languages, Lancount+1);
       Setlanguagename(Lancount, Lanname);
       Result := Lancount;
       INC(Lancount);
    end;
    
    function TLanchanger.Gettext(Textname: String): String;
    var
     I: Word;
     Lan: Tlanguage;
    begin
        Lan := Languages[Curlan];
        Result := 'Error';
        For I := 1 to high(Lan.texten) do
         If Uppercase(Lan.Texten[I].Textname) = Uppercase(Textname) then
          begin
            Result := Lan.Texten[I].textvalue;
            Break;
          end;
    end;
    
    procedure TLanchanger.Loadfromfile(const Filename: String);
    Var
     F: File of Tlanguage;
    begin
       Assignfile(F, Filename);
       Reset(F);
    
       Lancount := 1;
       While not EOF(F) do
        begin
          Setlength(Languages, Lancount+1);
          Blockread(F, languages[Lancount], 1);
          INC(Lancount);
        end;
    
       Closefile(F);
       Curlan := 1;
    end;
    
    procedure TLanchanger.Savetofile(const Filename: String);
    Var
     F: File of Tlanguage;
     I: Byte;
    begin
       Assignfile(F, Filename);
       Rewrite(F);
    
       I := 1;
       While I <= Lancount do
        begin
          Blockwrite(F, languages[I], 1);
          INC(I);
        end;
    
       Closefile(F);
    end;
    
    procedure TLanchanger.Setlanguagename(Lannr: Byte; Lanname: String);
    begin
       If Lannr > Lancount then
        Showmessage('Cannot change language name') else
         languages[Lannr].Lanname := Lanname;
    end;
    
    procedure TLanchanger.Updatecomponents;
    Var
     I: Word;
     Lan: Tlanguage;
     P: Ppropinfo;
     OBJ: Tobject;
    begin
       Lan := Languages[Curlan];
       For I := 1 to High( Lan.components ) do
        If Trim(Lan.Components[I].compname) <> '' then
        begin
          OBJ := Mainform.Findcomponent(Lan.components[I].compname);
          P := Getpropinfo(OBJ, Lan.components[I].Compprop);
           If P = NIL then Continue;
          Setstrprop(OBJ, P, Lan.components[I].value);
        end;
    end;
    Gebruik Typinfo in de uses-clause!!!!!!!!!

    door een Tlanchanger aan te maken, te creeaten en simpelweg de juiste procedures aanroept, wat parameters invoegen en je hebt een handige vertaler. Let op: Je hebt maar een deel van de code nog bij het eindproduct, en het andere deel is nodig voor schrijven. Maar het maakt eigenlijk nix uit.

    Code:
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Lan := Tlanchanger.Create;
      Lan.Mainform := Self;
       
      Lan.loadfromfile(FILENAME);
      Lan.updatecomponents;
    end;
    
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      Lan.Destroy;
    end;
    
    Procedure WRITESIMPLELANGUAGES;
    Var
     NL, EN: Byte;
     Lan: Tlanchanger;
    begin
       Lan := Tlanchanger.create;
    
      {creating a button with 2 languages}  
       NL := Lan.createnewlanguage('Nederlands');
       EN := Lan.createnewlanguage('Engels');
       Lan.addcomponent(NL, 'Button1', 'Caption', 'EEN TEST');
       Lan.addcomponent(EN, 'Button1', 'Caption', 'A TEST');
    
       Lan.savetofile('MY_LAN_FILE.LAF');
       //LAF = LAnguage File
       Lan.free;
    end;
    Kijk er maar even naar, vindt het zelf wel errug makkelijk zo.
    !

  11. #11
    notice-itter SvG's Avatar
    Join Date
    Apr 2002
    Location
    's-Hertogenbosch
    Posts
    4,865
    Sorry, verkeerde Createnewlanguage procedure:

    Code:
    function TLanchanger.Createnewlanguage(Lanname: String): Byte;
    begin
       INC(Lancount);
       Setlength(Languages, Lancount+1);
       Setlanguagename(Lancount, Lanname);
       Result := Lancount;
    end;
    !

  12. #12
    notice-itter SvG's Avatar
    Join Date
    Apr 2002
    Location
    's-Hertogenbosch
    Posts
    4,865
    Sorry hoor,

    mare, ik wil dit ff weten:

    nu heb ik mij toen zo uitgeleefd op deze code, en nu geeft er niemand een reply van:

    wowww, das een handige code

    sorry, dit moest ik ff kwijt
    !

  13. #13
    Senior Member PsychoMark's Avatar
    Join Date
    Nov 2001
    Location
    Raamsdonksveer
    Posts
    10,269
    wow, da's een handige code



    Sorry .




    [Edit]

    grmbl, laat ie weer die inline images niet zien
    Qui custodiet ipsos custodes

  14. #14
    notice-itter SvG's Avatar
    Join Date
    Apr 2002
    Location
    's-Hertogenbosch
    Posts
    4,865
    ik d8 al, wat is dit nu weer voor een link

    bleek dus een smilie te zijn
    !

  15. #15
    Eeeh, waarschijnlijk omdat ik niet snap wat de code doet, of gewoon omdat ik het niet nodig had?? Maar, hoe dan ook: ik waardeer het altijd weer dat iedereen hier elkaar helpt, dus ook in dit geval.

    En ik waardeer het ook als mensen me op foute foruminstellingen wijzen zodat ik die kan aanpassen en inline images het ook op dit forum doen
    Marcel

Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Replies: 5
    Last Post: 09-Apr-04, 21:37
  2. applicatie op meerdere locaties ...
    By bava in forum Koffiehoek
    Replies: 7
    Last Post: 14-Dec-03, 21:11

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •