IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Codes sources à télécharger Delphi Discussion :

[VCL] TConfFile, Une alternative aux fichiers INI.


Sujet :

Codes sources à télécharger Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Avatar de AbeBar27
    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2021
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2021
    Messages : 32
    Par défaut [VCL] TConfFile, Une alternative aux fichiers INI.
    Bonjour,

    Je vous propose un nouvel élément à utiliser : [VCL] TConfFile, Une alternative aux fichiers INI.

    J'ai souvent utilisé des fichiers .ini pour gérer divers paramètres de configuration.

    Toutefois, les fichiers .ini n’offrent que des fonctionnalités très limitées ce qui conduisait souvent à surcharger l’application *(en général des méthodes ReadConf et WriteConf) :

    • Lecture / écriture d’objet graphiques*: principalement TPen, TBrush et TFont

    • Lecture / écriture d’éléments énumérés d’un tableau de chaînes.

    • Lecture / écriture d’ensembles (comme le TStyles d’une fonte)

    • Absence de sous-section (en standard) ce qui conduit à des paires clef-valeur lourdes et difficiles à spécifier.

    • Pas de possibilité d’écrire la valeur d’une paire clé-valeur sur plusieurs lignes.

    • Les commentaires sont possibles mais mono ligne et sont perdus lorsque l’on met à jour le fichier ini par le code de l’application.

    D’autres formats existent qui permettent de décrire plus finement une grande variété de données tout en étant lisibles directement dans un éditeur avec ou sans coloration syntaxique (fichiers JSON, XML … ). Ces formats et les bibliothèques associées sont toutefois un peu lourds de mise en œuvre pour le but recherché.



    TConfFile et son descendant TGDIConfFile permettent de remédier à cela avec les possibilités :

    • De définir des sections et des sous-sections.

    • Préserve les commentaires mono et multi-lignes.

    • Permet les valeurs de paires clés-valeurs sur plusieurs lignes.

    • Gère les éléments énumérés d’un tableau de chaînes.

    • Gère les ensembles (comme le TStyles d’une fonte)

    • Gères les objets graphiques*TPen, TBrush et TFont



    Qu'en pensez-vous ?

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 170
    Par défaut
    Et le mode DFM fonctionne aussi ?
    Delphi a finalement déjà son propre format de sérialisation d'objet GDI natif.

    On peut facilement utiliser un TComponent en utilisant les fonctions de flux de Delphi pour serialiser beaucoup de descendant de TPersistent.
    Le gestionnaire de Style VCL utilise un objet Layout qui est un container d'un ensemble de TPersistent dont TFont et plus.


    Sinon, regarde un export de la Base de Registre, le format de cet export est aussi très intéressant, c'est un fichier ini a peu de chose près, cela montre comme mettre à plat l'arborescence en sous-section et la valeur est typée.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre confirmé
    Avatar de AbeBar27
    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2021
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2021
    Messages : 32
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Sinon, regarde un export de la Base de Registre, le format de cet export est aussi très intéressant, c'est un fichier ini a peu de chose près, cela montre comme mettre à plat l'arborescence en sous-section et la valeur est typée.
    Oui le format export de la base de registre est très exactement un fichier ini étendu avec les notions de section\sous-section\sous-sous-section\sous-sous-sous... (stop )
    Je cherchais juste à faire quelque chose de plus simple, lisible et éditable manuellement.

    Je n'ai pas bien compris votre question sur le mode DFM.
    S'agirait-il d'utiliser les classes TReader et TWriter de l'unité System.Classes ?
    J'y ai pensé mais j'avais l'impression de faire appel à un train de marchandises pour transporter une brouette de sable

    La conscience de l'imperfection préserve de l'intégrisme

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 170
    Par défaut
    Euh, juste partir de l'exemple ComponentToString (Delphi) mais oui c'est l'idée, sans même aller jusqu'à définir les TReader et TWriter, on peut faire un truc assez trivial

    Je n'ai pas regardé ton code en détail mais pour TFont, TPen, TBrush ... la sérialisation peut se faire en créant à la volée un TComponent qui ne sert que en tant que Container de sérialisation
    Idem tout ce qui est à base TStrings c'est facile mais TCollection demande un DefineProperties et des ReadCollections et WriteCollections, disons qu'il faut connaitre.

    Dans un vieux code, au lieu de sérialiser un record, j'avais utilisé un objet : [D5] Charger rapidement un type record

    Un peu comme les Experts JSON ou XML, tient comme dans ce sujet : Comment utiliser la liaison de fichier JSON ou l'on peut écrire leJsonVille.VILLE.BATIMENTS.Add(jsonbat) en manipulant l'objet de façon simple, on a tous fait ce genre de chose en XML ou en SOAP quand c'était à la mode

    De la même façon, on peut donc "figer" son objet config pour écrire un truc genre "Conf.Element.Champ.Valeur" ... en tout cas, j'utilise du JSON ou du XML pour ce genre de chose, et j'ai un code qui encapsule lecture et écriture du fichier pour que l'utilisation soit simple

    Alors, j'ai utilisé SetSubComponent pour avoir un DFM compact mais en dehors de créer l'objet Conf et ses items, le reste c'est juste le code issu de la doc : ComponentToString (Delphi)

    Code dfm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    object TMachin
      Text = 'Texte de Machine'
      Strings.Strings = (
        'Texte N'#176'1 de la Liste'
        'Texte N'#176'2 de la Liste'
        'Texte N'#176'3 de la Liste'
        'Texte N'#176'4 de la Liste'
        'Texte N'#176'5 de la Liste')
      Bidule.Font.Charset = DEFAULT_CHARSET
      Bidule.Font.Color = clWindowText
      Bidule.Font.Height = -11
      Bidule.Font.Name = 'Tahoma'
      Bidule.Font.Style = []
      Truc.Chose.Value = 666
      Truc.Text = 'Texte du Truc dans Machine'
    end

    Avec des objets simples TPersistent connu et quelques autres types, la seule chose à faire c'est déclaratif, juste on décrit en code la structure du fichier soit la classe racine TMachin

    - Unit1, la fiche avec un bouton
    - Config, un objet structuré
    - SampleComponentToString, le code exemple sur le Wiki Embarcadero

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    unit Unit1;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    uses Config, SampleComponentToString;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Machin: TMachin;
      S: string;
      I: Integer;
    begin
      Machin := TMachin.Create(nil);
      try
        Machin.Text := 'Texte de Machine';
        for I := 1 to 5 do
          Machin.Strings.Add(Format('Texte N°%d de la Liste', [i]));
        Machin.Truc.Text := 'Texte du Truc dans Machine';
        Machin.Truc.Chose.Value := 666;
        Machin.Bidule.Font := Self.Font;
     
        S := ComponentToStringProc(Machin);
      finally
        Machin.Free();
      end;
     
      ShowMessage(S);
     
      Machin := StringToComponentProc(S) as TMachin;
      try
        ShowMessage(Machin.Text + sLineBreak + Machin.Truc.Text + sLineBreak + Machin.Truc.Chose.Value.ToString() + sLineBreak + Machin.Strings.Text);
        ShowMessage(Machin.Bidule.Font.Name);
      finally
        Machin.Free();
      end;
    end;
     
    end.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
     
    unit Config;
     
    interface
     
    uses
      System.Classes, Vcl.Graphics;
     
    type
      TMachin = class(TComponent)
      public
        type
          TBidule = class(TComponent)
          private
            FFont: TFont;
            procedure SetFont(const Value: TFont);
          public
            constructor Create(AOwner: TComponent); override;
            destructor Destroy(); override;
          published
            property Font: TFont read FFont write SetFont;
          end;
          TTruc = class(TComponent)
          private
            type
              TChose = class(TComponent)
              private
                FValue: Integer;
              published
                property Value: Integer read FValue write FValue;
              end;
          private  private
            FChose: TChose;
            FText: string;
          public
            constructor Create(AOwner: TComponent); override;
            destructor Destroy(); override;
          published
            property Chose: TChose read FChose;
            property Text: string read FText write FText;
          end;
      private
        FText: string;
        FStrings: TStrings;
        FBidule: TBidule;
        FTruc: TTruc;
      protected
        procedure SetStrings(const Value: TStrings);
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy(); override;
      published
        property Text: string read FText write FText;
        property Strings: TStrings read FStrings write SetStrings;
        property Bidule: TBidule read FBidule;
        property Truc: TTruc read FTruc;
      end;
     
     
    implementation
     
    uses
      System.SysUtils;
     
    { TMachin }
     
    constructor TMachin.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
     
      FBidule := TBidule.Create(Self);
      FTruc := TTruc.Create(Self);
     
      FStrings := TStringList.Create();
     
      FBidule.SetSubComponent(True);
      FTruc.SetSubComponent(True);
    end;
     
    destructor TMachin.Destroy();
    begin
      FreeAndNil(FStrings);
     
      FTruc := nil;
      FBidule := nil;
     
      inherited Destroy();
    end;
     
    procedure TMachin.SetStrings(const Value: TStrings);
    begin
      FStrings.Assign(Value);
    end;
     
     
    { TMachin.TTruc }
     
    constructor TMachin.TTruc.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
     
      FChose := TChose.Create(Self);
     
      FChose.SetSubComponent(True);
    end;
     
    destructor TMachin.TTruc.Destroy();
    begin
      FChose := nil;
     
      inherited Destroy();
    end;
     
    { TMachin.TBidule }
     
    constructor TMachin.TBidule.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
     
      FFont := TFont.Create();
    end;
     
    destructor TMachin.TBidule.Destroy();
    begin
      FreeAndNil(FFont);
     
      inherited Destroy();
    end;
     
    procedure TMachin.TBidule.SetFont(const Value: TFont);
    begin
      FFont.Assign(Value);
    end;
     
    initialization
      RegisterClasses([TMachin, TMachin.TBidule, TMachin.TTruc, TMachin.TTruc.TChose]);
     
     
    end.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    unit SampleComponentToString;
     
    interface
     
    uses
      System.Classes;
     
    function ComponentToStringProc(Component: TComponent): string;
    function StringToComponentProc(Value: string): TComponent;
     
    implementation
     
    function ComponentToStringProc(Component: TComponent): string;
    var
      BinStream:TMemoryStream;
      StrStream: TStringStream;
      s: string;
    begin
      BinStream := TMemoryStream.Create;
      try
        StrStream := TStringStream.Create(s);
        try
          BinStream.WriteComponent(Component);
          BinStream.Seek(0, soFromBeginning);
          ObjectBinaryToText(BinStream, StrStream);
          StrStream.Seek(0, soFromBeginning);
          Result:= StrStream.DataString;
        finally
          StrStream.Free;
        end;
      finally
        BinStream.Free
      end;
    end;
     
    function StringToComponentProc(Value: string): TComponent;
    var
      StrStream:TStringStream;
      BinStream: TMemoryStream;
    begin
      StrStream := TStringStream.Create(Value);
      try
        BinStream := TMemoryStream.Create;
        try
          ObjectTextToBinary(StrStream, BinStream);
          BinStream.Seek(0, soFromBeginning);
          Result:= BinStream.ReadComponent(nil);
        finally
          BinStream.Free;
        end;
      finally
        StrStream.Free;
      end;
    end;
     
    end.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre confirmé
    Avatar de AbeBar27
    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2021
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2021
    Messages : 32
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Euh, juste partir de l'exemple ComponentToString (Delphi) mais oui c'est l'idée, sans même aller jusqu'à définir les TReader et TWriter, on peut faire un truc assez trivial

    Je n'ai pas regardé ton code en détail mais pour TFont, TPen, TBrush ... la sérialisation peut se faire en créant à la volée un TComponent qui ne sert que en tant que Container de sérialisation
    Idem tout ce qui est à base TStrings c'est facile mais TCollection demande un DefineProperties et des ReadCollections et WriteCollections, disons qu'il faut connaitre.
    Merci beaucoup pour ces infos très intéressantes, j'ai appris quelque chose d'utile
    L'exemple que tu m'as obligeamment fourni fonctionne immédiatement. Du coup je me suis précipité pour y ajouter une encapsulation de TFont dans un descendant de TComponent (que j'ai nommé TFontCapsule, c'est original !).
    Cela fonctionne parfaitement, la preuve :
    Nom : Copie écran.png
Affichages : 183
Taille : 14,8 Ko
    Ceci étant,
    • La seule amélioration obtenue par rapport à ma méthode est d'écrire le style en clair [fsBold,fsUnderline] plutôt que [05]. Mais si j'écris un TOpenDialog avec toutes les options cochées (cas d'école) je vais avoir un truc genre OpenDialog1.Options = [ofReadOnly, ofOverwritePrompt, ofHideReadOnly,ofNoChangeDir, ofShowHelp, ofNoValidate, ofAllowMultiSelect,ofExtensionDifferent, ofPathMustExist, ofFileMustExist, ofCreatePrompt,ofShareAware, ofNoReadOnlyReturn, ofNoTestFileCreate, ofNoNetworkButton,ofNoLongNames, ofOldStyleDialog, ofNoDereferenceLinks, ofEnableIncludeNotify,ofEnableSizing, ofDontAddToRecent, ofForceShowHidden]. Pas vraiment mon but !
    • Le code compilé me parait vite un peu lourd : 2*451*968 octets contre 2*760*192 octets pour mon appli ConfEditor qui utilise en plus des composants TSyntaxMemo, TGutter, TTreeView, TMenu, TOpenDialog, TPopUpMenu...


    Mais encore merci, la technique que tu proposes ouvre de nouveau horizons

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 170
    Par défaut
    Ah oui, le format DFM texte, c'est verbeux, et même le mode DFM Binaire ... surprise c'est aussi du texte
    C'est pour anticiper à mon avis un changement de l'ordre de l'énumération, si un petit malin insère une valeur en plein milieu, ça casserait la compatibilité ascendante en stockant le set sous forme de binaire

    C'est une chaine non affichable car c'est un binaire donc très vite on a des zéros qui stoppe les chaines dans les API Windows

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'TPF0'#7'TMachin'#0#4'Text'#6#$10'Texte de Machine'#$F'Strings.Strings'#1#$14#$16#0#0#0'Texte N°1 de la Liste'#$14#$16#0#0#0'Texte N°2 de la Liste'#$14#$16#0#0#0'Texte N°3 de la Liste'#$14#$16#0#0#0'Texte N°4 de la Liste'#$14#$16#0#0#0'Texte N°5 de la Liste'#0#$13'Bidule.Font.Charset'#7#$F'DEFAULT_CHARSET'#$11'Bidule.Font.Color'#7#$C'clWindowText'#$12'Bidule.Font.Height'#2'õ'#$10'Bidule.Font.Name'#6#6'Tahoma'#$11'Bidule.Font.Style'#$B#6'fsBold'#$B'fsUnderline'#0#$10'Truc.Chose.Value'#3'š'#2#9'Truc.Text'#6#$1A'Texte du Truc dans Machine'#0#0
    Tu peux modifier l'exemple ComponentToString ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    unit SampleComponentToString;
     
    interface
     
    uses
      System.Classes;
     
    function ComponentToStringProc(Component: TComponent; ADFMText: Boolean): string;
    function StringToComponentProc(Value: string; ADFMText: Boolean): TComponent;
     
    implementation
     
    function ComponentToStringProc(Component: TComponent; ADFMText: Boolean): string;
    var
      BinStream:TMemoryStream;
      StrStream: TStringStream;
      s: string;
    begin
      BinStream := TMemoryStream.Create;
      try
        StrStream := TStringStream.Create(s);
        try
          BinStream.WriteComponent(Component);
          BinStream.Seek(0, soFromBeginning);
          if ADFMText then
          begin
            ObjectBinaryToText(BinStream, StrStream);
            StrStream.Seek(0, soFromBeginning);
          end
          else
            StrStream.CopyFrom(BinStream, BinStream.Size);
     
          Result:= StrStream.DataString;
        finally
          StrStream.Free;
        end;
      finally
        BinStream.Free
      end;
    end;
     
    function StringToComponentProc(Value: string; ADFMText: Boolean): TComponent;
    var
      StrStream:TStringStream;
      BinStream: TMemoryStream;
    begin
      StrStream := TStringStream.Create(Value);
      try
        BinStream := TMemoryStream.Create;
        try
          if ADFMText then
            ObjectTextToBinary(StrStream, BinStream)
          else
            BinStream.CopyFrom(StrStream, StrStream.Size);
     
          BinStream.Seek(0, soFromBeginning);
          Result:= BinStream.ReadComponent(nil);
        finally
          BinStream.Free;
        end;
      finally
        StrStream.Free;
      end;
    end;
     
    end.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

Discussions similaires

  1. une alternative aux variables globales ?
    Par scheme dans le forum Général Python
    Réponses: 18
    Dernier message: 24/07/2009, 01h55
  2. Je cherche une alternative aux frames
    Par Gizmil dans le forum Général Conception Web
    Réponses: 9
    Dernier message: 02/11/2007, 09h40
  3. Je cherche une alternative aux frames
    Par Gizmil dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 29/10/2007, 15h25
  4. Résultat d'une requête dans fichier ini
    Par bruno28 dans le forum VBA Access
    Réponses: 6
    Dernier message: 13/06/2007, 17h29
  5. Changer le nom d'une section de fichier ini
    Par muquet dans le forum Langage
    Réponses: 4
    Dernier message: 27/01/2006, 14h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo