Un démarrage pour programmer un éditeur de texte simplifié

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Passage en V4

Code : Tout sélectionner

;;
; NotePB.pb : un "premier pas" pour un éditeur Notepad avec quelques limitations dans cette version, telle la limitation de la taille de chaines à 64K
;
; Ce code est envoyé sur le forum pour un usage pédagogique, il ne devrait pas être utilisé autrement sans l'accord de l'auteur.
; Il s'agit d'un logiciel faisant partie d'applications sous licence et non libre de droits.
; D'autres fonctions existent, ainsi qu'un interface utilisateur personnalisable sur demande à fweil@internext.fr.
;
; Ce code source PureBasic ne devrait pas s'exécuter correctement sur des plateformes non compatibles Windows, et exclusivement pour des utilisateurs disposant d'un environnement PureBasic sous licence.
;
; FWeil : 20040612
;
; Les commentaires sont proposés aux utilisateurs du forum PureBasic.
;
Enumeration
    #EditorGadget
    #MenuItem_New
    #MenuItem_Open
    #MenuItem_Save
    #MenuItem_SaveAs
    #MenuItem_Print
    #MenuItem_Close
    #MenuItem_Exit
    #MenuItem_Find
    #MenuItem_FindNext
    #MenuItem_Replace
    #MenuItem_Font
    #MenuItem_Help
    #MenuItem_Apropos
    #MenuItem_Nono
    #Window_Main
    #StatusBar
    #Menu
EndEnumeration

#TTS_RECTANGULAR = $10 ; Constantes API non prévues dans PureBasic pour la définition des bulles d'aide.
#TTS_RECTANGULARLIFT = $20
#TTS_BALLOON = $40

Global FileName.s, NLines.l, nchars.l, FontName.s, FontSize.l, FontColor.l, FontStyle.l

Procedure AddToolTip(Handle, Text.s) ; Ceci remplace la commande GadgetToolTip de PureBasic en donnant plus de possibilités pour ce type de gadget. Win32 API utilisée
    hToolTip = CreateWindowEx_(0, "tooltips_class32", "", $D0000000 | #TTS_BALLOON, 0, 0, 0, 0, WindowID(#Window_Main), 0, GetModuleHandle_(0), 0) ; Création d'une bulle.
    SendMessage_(hToolTip, #RB_SETTEXTCOLOR - 1, $C0FFFF, 0) ; Couleur d'avant-plan. Je sais pas pourquoi #RB_SETTEXTCOLOR - 1 !
    SendMessage_(hToolTip, #RB_SETBKCOLOR, $400000, 0) ; Couleur d'arrière plan
    SendMessage_(hToolTip, #RB_SIZETORECT + 1, 0, 180) ; Largeur max de la bulle. Je sais toujours pas pourquoi #RB_SIZETORECT + 1 !
    Button.TOOLINFO\cbSize = SizeOf(TOOLINFO) ; Structure pour remplir la bulle
    Button\uFlags = #TTF_IDISHWND | #TTF_SUBCLASS ; Indique que le membre uId est le handle. Si ce signal n'est pas mis, uId est l'identifiant de la bulle. | Indique que la bulle doit être sous classée pour récupérer des messages comme #WM_MOUSEMOVE. Si ce n'est pas précisé, il faudra utiliser le signal #TTM_RELAYEVENT pour envoyer les messages message au contrôle bulle. Pour une liste des messages utilisables par une bulle, voir #TTM_RELAYEVENT.
    Button\hwnd = Handle
    Button\uID = Handle
    Button\lpszText = @Text
    SendMessage_(hToolTip, #RB_SETBARINFO, 0, Button) ; Renvoie le contenu de la structure à la fenêtre bulle.
EndProcedure

Procedure SavePreferences(IniFileName.s)
    If CreatePreferences(IniFileName)
        WritePreferenceString("FontName", FontName)
        WritePreferenceLong("FontSize", FontSize)
        WritePreferenceLong("FontColor", FontColor)
        WritePreferenceLong("FontStyle", FontStyle)
        ClosePreferences()
    EndIf
EndProcedure

Procedure MenuItemWithShortcut(MenuItem.l, ItemText.s, Shortcut.l) ; Procédure pour créer un item de menu et le raccourci correspondant.
    MenuItem(MenuItem, ItemText)
    AddKeyboardShortcut(#Window_Main, Shortcut, MenuItem)
EndProcedure

Procedure ClearAll() ; Efface le contenu du gadget editeur et les variables associées.
    SetGadgetText(#EditorGadget, "")
    FileName = ""
    NLines = 0
    nchars = 0
EndProcedure

Procedure HighlightSelection(Handle.l, a.l, b.l)
    If a And b
        SendMessage_(Handle, #EM_SETSEL, a, b) ; Envoie un message pour fixer la sélection au handle indiqué. C'est une commande API. Cela permet de mettre en surbrillance les caractères de a à b dans le gadget correspondant au handle.
        SendMessage_(Handle, #EM_SCROLLCARET, 0, 0) ; Envoie un message pour faire défiler le contenu du gadget et positionner le curseur à un endroit donné.
    EndIf
EndProcedure

Procedure SaveContent(ThisFileName.s) ; Vérifie si le contenu du gadget peut être sauvegardé et effectue la sauvegarde.
    If CreateFile(0, ThisFileName)
        If nchars <= 64000
            WriteString(0,GetGadgetText(#EditorGadget))
            CloseFile(0)
            FileName = ThisFileName
        Else
            MessageRequester("Warning", "Save of more than 63999 chars is not possible", #PB_MessageRequester_Ok)
        EndIf
    Else
        MessageRequester("Warning", "File " + ThisFileName + " creation not possible", #PB_MessageRequester_Ok)
    EndIf
EndProcedure

Procedure MyStatusBar()
    CreateStatusBar(#StatusBar, WindowID(#Window_Main))
    AddStatusBarField(150)
    AddStatusBarField(450)
EndProcedure

; Programme principal.
;
Procedure wndProc(WindowID, message, wParam, lParam)
    Resultat = #PB_ProcessPureBasicEvents
   
    Select message
        Case #WM_SIZING ; Cet évènement est le redimensionnement de la fenêtre. #WM_SIZE est une constante API.
            ResizeGadget(#EditorGadget, 10, 0, WindowWidth(#Window_Main) - 20, WindowHeight(#Window_Main) - 40) ; Modifie la taille du gadget.
            FreeStatusBar(#StatusBar) ; Détruit la barre de status précédente et en recréé une.
            MyStatusBar()
            UpdateWindow_(WindowID)
    EndSelect
    ProcedureReturn Resultat
EndProcedure


FontName = "Verdana" ; Sélection d'une police existante.
FontSize = 12 ; Sélection d'une taille possible pour la police.
FontColor = #Black ; Une valeur RGB pour la couleur de la police. #Black est une constante PureBasic égale à 0.
FontStyle = 0 ; 0, #PB_Font_Bold, #PB_Font_Italic.
CR.s = Chr(13)
LF.s = Chr(10)
EOL.s = CR + LF
TAB.s = Chr(9)
CurrentDirectory.s = Space(#MAX_PATH) ; #MAX_PATH est une constante API qui donne la longueur maximale d'un chemin complet d'accès à un fichier (actuallement 260).
FileName = ""
GetCurrentDirectory_(#MAX_PATH, CurrentDirectory) ; Fixe CurrentDirectory au répertoire de démarrage du programme.
WorkingDirectory.s = CurrentDirectory ; Garde une copie de la valeur CurrentDirectory.
ProgramName.s = "NotePB 2" ; Utilisé dans le titre de la fenêtre et le nom du fichier .ini.
If OpenPreferences(ProgramName + ".ini") ; Tente de lire fichier ini ou en créé un s'il n'existe pas.
    FontName = ReadPreferenceString("FontName", FontName)
    FontSize = ReadPreferenceLong("FontSize", FontSize)
    FontColor = ReadPreferenceLong("FontColor", FontColor)
    FontStyle = ReadPreferenceLong("FontStyle", FontStyle)
    ClosePreferences()
Else
    SavePreferences(ProgramName + ".ini") ; Enregistre les paramètres d'initialisation.
EndIf
Quit.l = #False
hwnd.l = OpenWindow(#Window_Main, 0, 0, 320, 240, ProgramName, #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
If hwnd
    SetWindowCallback(@wndProc())
    AddKeyboardShortcut(#Window_Main, #PB_Shortcut_Escape, #PB_Shortcut_Escape)
    CreateGadgetList(hwnd)
    SetGadgetFont(#PB_Default, LoadFont(0, FontName, FontSize, FontStyle)) ; Change la valeur de la police pour les gadgets.
    hEditorGadget = EditorGadget(#EditorGadget, 10, 0, WindowWidth(#Window_Main) - 20, WindowHeight(#Window_Main) - 40) ; Créé un nouveau gadget.
    AddToolTip(hEditorGadget, "Vous pouvez utiliser tous les raccourcis et menus" + EOL + "incluant également les raccourcis standards de Windows :" + EOL + "Couper (CTRL+X)" + EOL + "Copier (CTRL+C)" + EOL + "Coller (CTRL+V)" + EOL + "Tout sélectionner (CTRL+A)")
    format.CHARFORMAT\cbSize = SizeOf(CHARFORMAT) ; Prépare les attributs de couleur dans la structure appropriée pour envoyer les informations au gadget.
    format\dwMask = #CFM_COLOR ; Constante API. Le membre crTextColor et la valeur #CFE_AUTOCOLOR du membre dwEffects sont valides.
    format\crTextColor = FontColor ; Couleur du texte. Ce membre est ignoré si #CFE_AUTOCOLOR est spécifié. Met à jour la police après appel du FontRequester.
    SendMessage_(hEditorGadget, #EM_SETCHARFORMAT, 0, @format) ; Envoie l'information de couleur pour le gadget. Appel API.
    CreateMenu(#Menu, hwnd) ; Créé le menu avec titres et items. ALT + première lettre active l'entrée d'un menu. En appuyant ensuite sur la lettre marquée, on accède à l'item.
    MenuTitle("Fichier")
    MenuItemWithShortcut(#MenuItem_New, "&Nouveau" + TAB + "CTRL+N", #PB_Shortcut_Control | #PB_Shortcut_N)
    MenuItemWithShortcut(#MenuItem_Open, "&Ouvrir" + TAB + "CTRL+O", #PB_Shortcut_Control | #PB_Shortcut_O)
    MenuItemWithShortcut(#MenuItem_Save, "&Sauver" + TAB + "CTRL+S", #PB_Shortcut_Control | #PB_Shortcut_S)
    MenuItemWithShortcut(#MenuItem_SaveAs, "Sauver &Comme" + TAB + "MAJ+CTRL+S", #PB_Shortcut_Control | #PB_Shortcut_S | #PB_Shortcut_Shift)
    MenuItemWithShortcut(#MenuItem_Print, "&Print" + TAB + "MAJ+CTRL+P", #PB_Shortcut_Control | #PB_Shortcut_P | #PB_Shortcut_Shift)
    MenuItemWithShortcut(#MenuItem_Close, "&Fermer" + TAB + "CTRL+W", #PB_Shortcut_Control | #PB_Shortcut_W)
    MenuBar()
    MenuItemWithShortcut(#MenuItem_Exit, "&Terminer" + TAB + "CTRL+Q", #PB_Shortcut_Control | #PB_Shortcut_Q)
    MenuTitle("Editer")
    MenuItemWithShortcut(#MenuItem_Find, "&Chercher" + TAB + "CTRL+F", #PB_Shortcut_Control | #PB_Shortcut_F)
    MenuItemWithShortcut(#MenuItem_FindNext, "Chercher &Suivant" + TAB + "F3", #PB_Shortcut_F3)
    MenuItemWithShortcut(#MenuItem_Replace, "&Remplacer" + TAB + "CTRL+H", #PB_Shortcut_Control | #PB_Shortcut_H)
    MenuTitle("Affichage")
    MenuItemWithShortcut(#MenuItem_Font, "&Police" + TAB + "MAJ+CTRL+F", #PB_Shortcut_Control | #PB_Shortcut_F | #PB_Shortcut_Shift)
    MenuTitle("Aide")
    MenuItemWithShortcut(#MenuItem_Help, "&Aide" + TAB + "F1", #PB_Shortcut_F1)
    MenuItemWithShortcut(#MenuItem_Apropos, "A&propos" + TAB + "F12", #PB_Shortcut_F12)
    MenuTitle("Nono")
    MenuItemWithShortcut(#MenuItem_Nono, "&Parle" + TAB + "F9", #PB_Shortcut_F9)
    MyStatusBar()
   
   
    Repeat ; Voici la boucle principale de gestion d'évènements. Elle est basée sur un WaitWindowEvent. Trois entrée principales sont données : #PB_Event_CloseWindow, #PB_Event_Menu et #WM_SIZE.
        Select WaitWindowEvent()
            Case #PB_Event_CloseWindow ; Commutateur Quit pour quitter le programme.
                Quit = #True
            Case #PB_Event_Menu ; Les évenements menus générés par le clavier avec les raccourcis, ou les accès aux menus sont traités ici.
                Select EventMenu()
                    Case #MenuItem_New ; Génère un effacement du contenu du gadget éditeur et des variables associées.
                        ClearAll()
                    Case #MenuItem_Open ; Ouvre un fichier après avoir effacé le contenu du gadget éditeur. Remplit le gadget éditeur avec le contenu du fichier.
                        ClearAll()
                        FileName = OpenFileRequester("Choisir le fichier à ouvrir", WorkingDirectory + "\" + FileName, "*.*", 0)
                        If ReadFile(0, FileName)
                            Repeat
                                a$ = ReadString(0)
                                AddGadgetItem(#EditorGadget, NLines, a$)
                                NLines + 1 ; NLines et NChars sont des variables statistiques, mais servent également à la fonction recherche.
                                nchars + Len(a$) + 2
                            Until Eof(0)
                            CloseFile(0)
                        EndIf
                    Case #MenuItem_Save ; Enregistre le contenu du gadget éditeur dans le fichier précédemetn ouvert.
                        SaveContent(FileName)
                    Case #MenuItem_SaveAs ; Enregistre le contenu du gadget éditeur dans un fichier dont le nom est saisi par l'utilisateur.
                        SaveContent(SaveFileRequester("Choisir le nom du fichier à enregistrer", WorkingDirectory + "\" + FileName, "*.*", 0))
                    Case #MenuItem_Close ; Cette commande est redondante avec New.
                        ClearAll()
                    Case #MenuItem_Exit ; Commute cette variable de faux à vrai pour sortir du programme.
                        Quit = #True
                    Case #MenuItem_Find ; Demande à l'utilisateur un masque de recherche et positionne le contenu du gadget éditeur sur la première occurence trouvée.
                        Text.s = InputRequester("Trouver", "Entrez le texte à trouver", Text)
                        a$ = GetGadgetText(#EditorGadget)
                        b$ = ReplaceString(a$, EOL, LF)
                        StartPos = FindString(b$, Text, 1) - 1
                        HighlightSelection(hEditorGadget, StartPos, StartPos + Len(Text))
                    Case #MenuItem_FindNext ; Fait défiler le contenu du gadget à la prochaine occurence correspondant au masque de recherche. Cette recherche est circulaire. Si la fin du contenu est atteinte, on continue en reprenant au début.
                        a$ = GetGadgetText(#EditorGadget)
                        b$ = ReplaceString(a$, EOL, LF)
                        StartPos = FindString(b$ , Text, StartPos + Len(Text)) - 1 ; Trouve la position de la prochaine occurence
                        HighlightSelection(hEditorGadget, StartPos, StartPos + Len(Text))
                    Case #MenuItem_Replace ; Remplace toutes les occurences Text par ReplaceText dans le contenu du gadget éditeur.
                        Text.s = InputRequester("Remplacer", "Entrer le texte à trouver", Text)
                        ReplaceText.s = InputRequester("Remplacer", "Remplacer par", ReplaceText)
                        a$ = GetGadgetText(#EditorGadget)
                        b$ = ReplaceString(a$, Text, ReplaceText)
                        SetGadgetText(#EditorGadget, b$)
                    Case #MenuItem_Font ; Ouvre un sélecteur de polices avec les attributs étendus pour changer la police, les attributs et la couleur. Mauvaise donne pour la couleur, ça ne fonctionne pas pour l'instant.
                        FontRequester(FontName, FontSize, #PB_FontRequester_Effects)
                        FontName = SelectedFontName() ; Mise à jour du nom de la police.
                        If SelectedFontSize() ; Mise à jour de la taille. Optionnel au cas où l'on termine le sélecteur sans faire de choix.
                            FontSize = SelectedFontSize()
                        EndIf
                        FontColor = SelectedFontColor() ; Mise à jour de la couleur.
                        FontStyle = SelectedFontStyle() ; Mise à jour du style.
                        a$ = GetGadgetText(#EditorGadget) ; Il est nécessaire de détruire les gadgets, avant de les recréer avec les nouveaux attributs. il sera également nécessaire de recharger le fichier en cours dans le gadget éditeur.
                        FreeGadget(#EditorGadget) ; Destruction du gadget.
                        SetGadgetFont(#PB_Default, LoadFont(0, FontName, FontSize, FontStyle)) ; Changement de la police à utiliser.
                        hEditorGadget = EditorGadget(#EditorGadget, 10, 0, WindowWidth(#Window_Main) - 20, WindowHeight(#Window_Main) - 40) ; Création d'un nouveau gadget.
                        AddToolTip(hEditorGadget, "Vous pouvez utiliser tous les raccourcis clavier et menus" + EOL + "incluant également les raccourcis standards de Windows :" + EOL + "Couper (CTRL+X)" + EOL + "Copier (CTRL+C)" + EOL + "Coller (CTRL+V)" + EOL + "Tout sélectionner (CTRL+A)")
                        format.CHARFORMAT\cbSize = SizeOf(CHARFORMAT) ; Prépare les attributs de couleur dans la structure appropriée avant de les envoyer au gadget.
                        format\dwMask = #CFM_COLOR ; Constante API. Le membre crTextColor et la valeur #CFE_AUTOCOLOR du membre dwEffects sont valides.
                        format\crTextColor = FontColor ; Couleur du texte. Ce membre est ignoré si #CFE_AUTOCOLOR est spécifié. Met à jour la police après appel du FontRequester.
                        SendMessage_(hEditorGadget, #EM_SETCHARFORMAT, 0, @format) ; Envoie l'information de couleur pour le gadget. Appel API.
                        SetGadgetText(#EditorGadget, a$) ; Remplit le gadget avec le contenu précédement stocké.
                    Case #MenuItem_Help
                        HelpMessage.s = "NotePB 2 - Aide en ligne" + EOL
                        HelpMessage = HelpMessage + "" + EOL
                        HelpMessage = HelpMessage + "Vous pouvez utiliser les menus et raccourcis" + EOL
                        HelpMessage = HelpMessage + "" + EOL
                        HelpMessage = HelpMessage + "Fichier Nouveau = CTRL+N" + EOL
                        HelpMessage = HelpMessage + "Fichier Ouvrir = CTRL+O" + EOL
                        HelpMessage = HelpMessage + "Fichier Sauver = CTRL+S" + EOL
                        HelpMessage = HelpMessage + "Fichier Sauver Comme = MAJ+CTRL+S" + EOL
                        HelpMessage = HelpMessage + "Fichier Fermer = CTRL+W" + EOL
                        HelpMessage = HelpMessage + "Terminer = CTRL+Q" + EOL
                        HelpMessage = HelpMessage + "Chercher = CTRL+F" + EOL
                        HelpMessage = HelpMessage + "Chercher Suivant = F3" + EOL
                        HelpMessage = HelpMessage + "Remplacer= CTRL+H" + EOL
                        HelpMessage = HelpMessage + "Police = MAJ+CTRL+F" + EOL
                        HelpMessage = HelpMessage + "Aide = F1" + EOL
                        HelpMessage = HelpMessage + "Apropos = F12" + EOL
                        HelpMessage = HelpMessage + "" + EOL
                        HelpMessage = HelpMessage + "Vous disposez également des raccourcis 'classiques' :" + EOL
                        HelpMessage = HelpMessage + "" + EOL
                        HelpMessage = HelpMessage + "Couper (CTRL+X)" + EOL
                        HelpMessage = HelpMessage + "Copier  (CTRL+C)" + EOL
                        HelpMessage = HelpMessage + "Coller (CTRL+V)" + EOL
                        HelpMessage = HelpMessage + "Tout sélectionner (CTRL+A)"
                        MessageRequester("NotePB 2 - Aide", HelpMessage, #PB_MessageRequester_Ok)
                    Case #MenuItem_Apropos
                        HelpMessage.s = "NotePB 2 - Apropos" + EOL
                        HelpMessage = HelpMessage + "" + EOL
                        HelpMessage = HelpMessage + "Créé par fweil@internext.fr" + EOL
                        HelpMessage = HelpMessage + "Cette version est NotePB 2 : publié le 2004/05/17" + EOL
                        HelpMessage = HelpMessage + "" + EOL
                        HelpMessage = HelpMessage + "Ce programme n'est pas un logiciel libre." + EOL
                        HelpMessage = HelpMessage + "Merci de nous contacter pour plus d'informations" + EOL
                        MessageRequester("NotePB 2 - Apropos", HelpMessage, #PB_MessageRequester_Ok)
                    Case #MenuItem_Print
                        If PrintRequester()
                            If StartPrinting("NotePad 2")
                                StartDrawing(PrinterOutput())
                                PrinterFontSize = FontSize * 3
                                PrinterFontHeight = 3 * PrinterFontSize / 2
                                PrinterDPI = 360
                                PrinterTopMargin = PrinterDPI
                                PrinterLeftMargin = PrinterDPI
                                PrintYLocation = PrinterTopMargin
                                PrintXLocation = PrinterLeftMargin
                                DrawingFont(LoadFont(23, FontName, PrinterFontSize, FontStyle))
                                BackColor(RGB(255, 255, 255))
                                FrontColor(FontColor)
                                DrawingMode(1)
                                For i = 0 To CountGadgetItems(#EditorGadget) - 1
                                    PrintYLocation + PrinterFontHeight
                                    DrawText(PrintXLocation, PrintYLocation,GetGadgetItemText(#EditorGadget, i, 0))
                                    If PrintYLocation > 10 * PrinterDPI
                                        NewPrinterPage()
                                        PrintYLocation = PrinterTopMargin
                                    EndIf
                                Next
                                StopDrawing()
                                StopPrinting()
                            EndIf
                        EndIf
                    Case #MenuItem_Nono
                        For i = 0 To CountGadgetItems(#EditorGadget) - 1
                            phrase.s=(GetGadgetItemText(#EditorGadget, i, 0)) 
                            If OpenLibrary(0, "nono2004.dll") And  Len(phrase.s)>1
                                ;************************
                                panoramique=125:; le son sera sur les 2 haut-parleurs (0 tout a gauche) (255 tout a droite)
                                Frequence=11025
                                CallFunction(0, "nono2004", phrase.s,Frequence,panoramique)  ;appel la dll et lui passe la phrase a dire 
                           
                            EndIf
                        Next
                         Quit = #False
                       ; CallFunction(0, "nono2004", "/." ,Frequence,panoramique)  ;appel la dll et lui passe la phrase a dire
                    Case #PB_Shortcut_Escape ; Commute pour sortir du programme.
                        Quit = #True
                    Default
                EndSelect
            Case #PB_Event_Gadget
                Select EventGadget()
                    Case #EditorGadget
                        *Buffer = AllocateMemory(64000)
                        Debug SendMessage_(hEditorGadget, #EM_GETSELTEXT, 0, *Buffer)
                        TextCapture.s = PeekS(*Buffer)
                        FreeMemory(*Buffer)
                EndSelect
            Case #WM_SIZING ; Cet évènement est le redimensionnement de la fenêtre. #WM_SIZE est une constante API.
                Debug "WM_SIZING"
                ResizeGadget(#EditorGadget, 10, 0, WindowWidth(#Window_Main) - 20, WindowHeight(#Window_Main) - 40) ; Modifie la taille du gadget.
                FreeStatusBar(#StatusBar) ; Détruit la barre de status précédente et en recréé une.
                MyStatusBar()
               
            Default
        EndSelect
        StatusBarText(#StatusBar, 0, FormatDate("%dd/%mm/%yyyy", Date()) + " " + FormatDate("%hh:%ii:%ss", Date()))
        StatusBarText(#StatusBar, 1, FileName + " " + Str(Len(GetGadgetText(#EditorGadget))) + " chars " + Str(NLines) + " lines " + Str(nchars)) ; Affiche le nom du ficher actuel et les statistiques.
    Until Quit
    SavePreferences(ProgramName + ".ini") ; Enregistres les valeurs des préférences.
EndIf
End 
Répondre