Mon premier programme : TiCreateFile

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
titraxx
Messages : 10
Inscription : mar. 22/mars/2011 19:25

Mon premier programme : TiCreateFile

Message par titraxx »

Bonsoir,

Lorsque j'ai découvert PureBasic, j'avais commencé par écrire un programme permettant de créer des fichiers de taille voulu. J'ai arrêté PureBasic et je n'ai jamais fini ce programme. J'avais commencé ici : http://www.purebasic.fr/french/viewtopi ... =1&t=11660.
J'ai repris dernièrement le developpement de ce programme et j'aurais voulu avoir vos avis ainsi que vos suggestions.

Le programme est basique : on choisit la taille du fichier que l'on veut créer, son chemin et le programme le génère.
J'ai mis une limite de taille dans le cas ou l'unité est le Mo mais je n'en ai pas encore mis sur les autres alors je vous conseille d'éviter de rentrer des valeurs énorme (enfin, c'est vous qui voyez :mrgreen:). D'ailleurs au dessus d'une certaine taille, le programme est si occupé que la fenêtre se fige ("... ne répond pas…").

Toute suggestion m'intéresse, que ce soit pour l'interface, la technique utilisée ou quoi que ce soit d'autre.
Merci,

TitraxX

Code : Tout sélectionner

;######################################
; programme : TiCreateFile
; version : 0.0
; description : programme qui permet de créer un fichier de taille souhaité
; détails :
; ajouts prévus :
; auteur : titraxx
; date création : 08/01/2012
; dernière mise à jour: 18/01/2012
;######################################


;---- Variables ----
Global cheminFichierDefaut$ = GetPathPart(ProgramFilename()) + "bin"  ;le chemin par défaut du fichier, avec le nom de fichier "bin"
;il faut activer une option pour gérer le dossier de démarrage : Compilateur/Options/compiler-éxecuter et cocher executable dans rep source
Debug "chemin par défaut: " + cheminFichierDefaut$ 
Global cheminFichierChoisi$ = ""
Debug cheminFichierChoisi$

;---- Énumérations----
Enumeration
  #fichier
EndEnumeration
;---- Déclaration des Procédures ----
Declare bouton_parcourir()
Declare bouton_creer()
Declare ecrire_fichier(unite, coef)

;########################################################################### CETTE PARTIE EST NORMALEMENT DANS UN FICHIER A PART ET EST INTÉGRÉ PAR UN "INCLUDE" (modifié pour le forum)
Enumeration
  #fenetre_principale
EndEnumeration

;- Gadget Constants
;
Enumeration
  #Text_0
  #coef_unite
  #liste_unite
  #bouton_creer
  #string_chemin_fichier
  #bouton_parcourir
EndEnumeration


Procedure Open_fenetre_principale()
  If OpenWindow(#fenetre_principale, 411, 107, 350, 210, "TiCreateFile",  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_TitleBar )

      TextGadget(#Text_0, 10, 10, 330, 20, "Entrez la taille du fichier que vous souhaitez créer et cliquez sur Créer")
      StringGadget(#coef_unite, 60, 60, 100, 20, "", #PB_String_Numeric)
      ComboBoxGadget(#liste_unite, 190, 60, 100, 20)
      ButtonGadget(#bouton_creer, 10, 130, 330, 50, "Créer")
      StringGadget(#string_chemin_fichier, 30, 95, 230, 20, "", #PB_String_ReadOnly)
      ButtonGadget(#bouton_parcourir, 270, 95, 30, 20, "...")
      

  EndIf
EndProcedure
;#################################################################### FIN DE LA PARTIE INCLUDE

Open_fenetre_principale()
  AddGadgetItem(#liste_unite,0,"o (octet)")
  AddGadgetItem(#liste_unite, 1,"ko (kilooctet)")
  AddGadgetItem(#liste_unite, 2, "Mo (Megaoctet)")
  SetGadgetState(#liste_unite, 0)
  Debug "Open fenetre :" + cheminFichierDefaut$
   
Repeat ;début de la boucle principale du programme.
  Event = WaitWindowEvent()
    Select EventGadget()
      Case #bouton_creer
        bouton_creer()  
      Case  #bouton_parcourir
        bouton_parcourir()        
    EndSelect
  Until Event = #PB_Event_CloseWindow ;fin de la boucle principale du programme.
  
  ;---- Procédures ----
Procedure bouton_parcourir()
  choixFait = 0 ;boucle permettant d'ouvrir à nouveau SaveFileRequester en cas de collision et si l'utilisateur dis "non"
    Repeat
      Debug "bouton parcourir"
      Debug cheminFichierDefaut$
      cheminFichierChoisi$ = SaveFileRequester("Choisissez l'emplacement où vous souhaitez enregistrer le fichier", cheminFichierDefaut$, "Tous les fichiers (*.*)|*.*", 0)
      Debug cheminFichierChoisi$
      
      If cheminFichierChoisi$ ;on vérifie que le chemin est valide
        Debug Chr(10) + cheminFichierChoisi$
        If FileSize(cheminFichierChoisi$) = -1 ;on vérifie que le programme ne va pas écraser un fichier déjà existant
          ;##########Le fichier n'écrase rien######################
          Debug "Le fichier que l'on veut créer n'écrase pas un fichier déjà existant"
          choixFait = 1
          SetGadgetText(#string_chemin_fichier, cheminFichierChoisi$)
        Else ;traitement de l'écrasement de fichier
        ;###############Le fichier va écraser un fichier #######################
          Debug"Le fichier que l'on veut créer va écraser un fichier déjà existant"
          resultatMessageRequester = MessageRequester("Attention !", "Le fichier " + cheminFichierChoisi$ + " existe déjà !" + Chr(13) + "Etes vous sûr de vouloir l'écraser ?", #PB_MessageRequester_YesNoCancel)
          Select resultatMessageRequester
            Case #PB_MessageRequester_Yes
              choixFait = 1
              SetGadgetText(#string_chemin_fichier, cheminFichierChoisi$)
              Debug "Cliqué sur oui dans le MessageRequester" 
            Case #PB_MessageRequester_No
              choixFait = 0
              cheminFichierChoisi$ = ""
            Case #PB_MessageRequester_Cancel
              Debug "CANCEL" + Str(choixFait)
              choixFait = 1
              cheminFichierChoisi$ = ""            
          EndSelect
        EndIf
      Else
        Debug "La sélection a été annulée"
        choixFait = 1
      EndIf
    Until choixFait = 1
  Debug "CHOIX FINAL = " + cheminFichierChoisi$    
EndProcedure

Procedure bouton_creer() ;gere la pression du bonton Créer (string_chemin_fichier vide ? Coefficient vide ?). Crée le fichier puis demande à la fonction ecrire_fichier() d'écrire la quantité qu'il faut.
  a$ = GetGadgetText(#coef_unite)
  gadgetstate.b = GetGadgetState(#liste_unite)
  Debug "coefficient :" + a$ + " Gadgetstate: " + Str(gadetstate)
  If a$ = "" Or a$ = "0"
    Debug "zéro ou rien (vide) dans le StrinGadget"
    MessageRequester("Information", "Veuillez entrer la taille du fichier !", 0)
  ElseIf Val(a$) > 500 And gadgetstate = 2
    MessageRequester("Valeur trop grande", "Le fichier que vous voulez créer est trop gros, le programme risquerait de planter", 0)
  ElseIf  cheminFichierChoisi$ = ""
    MessageRequester("Aucun emplacement choisi", "Aucun emplacement n'a été choisi, merci de spécifier où enregistrer le fichier", 0)
  Else 
    If CreateFile(#fichier, cheminFichierChoisi$)
      Select gadgetstate
        Case 0
          Debug "Unité : OCTET"
          ecrire_fichier(1, Val(a$) )
        Case 1
          Debug "Unité : KILO"
          ecrire_fichier(1024, Val(a$) )
        Case 2
          ecrire_fichier(1048576, Val(a$) )
      EndSelect
      CloseFile(#fichier)
      MessageRequester("Fichier créé", "Le fichier a bien été créé", 0)          
    EndIf          
  EndIf
EndProcedure

Procedure ecrire_fichier(unite, coef) ;crée le fichier en fonction de l'unite choisi.
  Debug "Dans ecrire_fichier(), unite = " + Str(unite) + " coef " + Str(coef)
  *MemoireID = AllocateMemory(unite)
  If *MemoireID
    For i=1 To coef
      WriteData(#fichier, *MemoireID, unite)
      Debug  cheminFichierChoisi$ + Str(FileSize(cheminFichierChoisi$))
    Next
    FreeMemory(*MemoireID)
  Else
    MessageRequester("Erreur", "Erreur lors de la création du fichier", 0)
  EndIf
EndProcedure
; IDE Options = PureBasic 4.60 (Windows - x64)
; CursorPosition = 28
; FirstLine = 6
; Folding = -
; EnableXP
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Mon premier programme : TiCreateFile

Message par Backup »

cool !

mais ça sert a quoi ? 8O (de creer un fichier de x kilos/mega/tera)
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Mon premier programme : TiCreateFile

Message par Ar-S »

Dobro a écrit :cool !
mais ça sert a quoi ? 8O (de creer un fichier de x kilos/mega/tera)
à se faire la main :)

J'ai pas testé mais à vu d'oeil ça a l'ai correcte.
J'ai même découvert le PB_MessageRequester_Yes / No (j'utilisais les chiffres)
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
titraxx
Messages : 10
Inscription : mar. 22/mars/2011 19:25

Re: Mon premier programme : TiCreateFile

Message par titraxx »

Ça peut servir pour faire des test de transfert de fichier mais bon c'est surtout pour m'entrainer car c'est assez simple.

Vous voyez une meilleure méthode pour générer ces fichiers ? Car si l'utilisateur demande de créer un gros fichier le programme se fige, il y a un moyen d'éviter cela ?

De plus j'ai remarqué que le programme ne consomme que 1,6 Mo une fois lancer mais dès que je clique sur le bouton pour parcourir (saveFileRequester) la consommation passe à 9-10 Mo, est-ce normal ?

Je pose toute ces questions histoire de partir sur des bonnes bases, donc si vous voyez des aberrations ou des choses à améliorer je prends :)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Mon premier programme : TiCreateFile

Message par Backup »

titraxx a écrit : Car si l'utilisateur demande de créer un gros fichier le programme se fige, il y a un moyen d'éviter cela ?
pas testé mais peut etre un

Code : Tout sélectionner

WindowEvent() :delay(2)
apres la ligne

Code : Tout sélectionner

For i=1 To coef
a tester ... ;)
Cls
Messages : 620
Inscription : mer. 22/juin/2005 8:51
Localisation : Nantes

Re: Mon premier programme : TiCreateFile

Message par Cls »

titraxx a écrit :Vous voyez une meilleure méthode pour générer ces fichiers ? Car si l'utilisateur demande de créer un gros fichier le programme se fige, il y a un moyen d'éviter cela ?
Salut,
tu peux utiliser un Thread pour générer le fichier et/ou pour la gestion de l'interface.

A+
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Mon premier programme : TiCreateFile

Message par Le Soldat Inconnu »

sinon, insérer un

Code : Tout sélectionner

While WindowEvent() : Wend
dans le boucle d'écriture du fichier

et pas WindowEvent() : Delay(2), désolé Dobro, mais cela ne vide pas la pile d'évènements :mrgreen:
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Mon premier programme : TiCreateFile

Message par Ar-S »

Je plussoie à l'idée du thread, car pour un gros fichier, ça prendra forcement le temps que ça prendra et figera ta fenêtre (même si ça reste sans conséquence sur la création même du fichier).
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
titraxx
Messages : 10
Inscription : mar. 22/mars/2011 19:25

Re: Mon premier programme : TiCreateFile

Message par titraxx »

J'ai essayé la méthode de LSI...

Code : Tout sélectionner

While WindowEvent() : Wend
...et cela fonctionne (l'interface ne se fige plus) mais je ne comprend pas très bien ce qu'il se passe, pourquoi le programme ne se fige plus ?
Du coup, maintenant que l'interface ne se fige plus l'utilisateur reste devant la fenêtre mais il ne sait pas que ce qui se passe, du coup je vais tenter de faire une barre de progression de la génération :)

Pour les threads je vais essayer d'y travailler.
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Mon premier programme : TiCreateFile

Message par graph100 »

sur windows, et sur d'autre système d'ailleurs, le système d'exploitation communique avec le programme par des messages.
avec Pb, tu les récupères avec les commandes WaitWindowEvent() et WindowEvent(), la 1ere est bloquante et attend un message pour continuer alors que la seconde ne bloque pas le programme.

Il y a un message pour chaque action sur la fenetre, et, de même tout ce qui touche à l'interface et au dessin de ta fenêtre est géré par message. Donc si tu ne les traites pas, la fenetre n'est pas dessinée et les boutons ne fonctionnent pas (etc..).

Le code donné :

Code : Tout sélectionner

While WindowEvent() : Wend
permet de parcourir toute la pile des message que windows a envoyé à ton prog, cela permet de les traiter, et ensuite, quand il n'y en a plus, le programme poursuit.
Cette méthode a pour avantage sa facilité de mise en oeuvre (c'est rapide et cela permet de poursuivre le prog), mais elle a un énorme désavantage : tu ne traites pas les évènements toi même (il faut ajouter un traitement pour chaque évènement) et cela ralenti considérablement ton programme : si tu bouges ta souris au dessus de la fenetre, la pile de message va grandir énormément, et donc prendre plus de temps a être traitée.

Si tu veux un traitement rapide d'un truc en particulier, et que tu ne veux pas bloquer ton programme, comme une écriture dans un fichier, ou bien, une génération d'image, il faut que tu utilises un thread.

C'est assez simple, et avec ton prog exemple, ça va te faire un très bon entrainement.
Tu pourras aussi t'entrainer à mettre une barre de progression sur la fenêtre principale, mise à jour par une valeur du thread, mais à intervalles réguliers

je te file un court exemple :

Le code suivant lance la calculatrice de windows et attend que tu la fermes en affichant des pointillés qui s'ajoutent, ensuite il affiche un texte différent.

Code : Tout sélectionner

Global IS_pointille.b = #False

Procedure Pointille(bla)
	a = 0
	
	Repeat
		SetGadgetText(0, LSet("Attente ", 8 + a, "."))
		
		a + 1
		If a = 5 : a = 0 : EndIf
		
		Delay(500)
	Until IS_pointille = #True
	
	SetGadgetText(0, "Le programme est fermé")
EndProcedure

Procedure LancementProgramme(*adresse_nom_prog)
	id_prog = RunProgram(PeekS(*adresse_nom_prog), "", "", #PB_Program_Open)
	
	If id_prog
		WaitProgram(id_prog)
	EndIf
	
EndProcedure


If OpenWindow(0, 0, 0, 140, 40, "blabla", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
	TextGadget(0, 10, 10, 120, 20, "Attente")
EndIf


; lancement des pointillés d'attente
thread_pointille = CreateThread(@Pointille(), 0)

; lancement du thread de lancement du programme
; prog.s = "C:\Windows\System32\calc.exe"
prog.s = "calc.exe"
thread_program = CreateThread(@LancementProgramme(), @prog)

Repeat
	event = WaitWindowEvent(100)
	
	If IsThread(thread_program) = 0
		IS_pointille = #True
	EndIf
	
Until event = #PB_Event_CloseWindow

End
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Répondre