[Résolu] Problème avec l'utilisation de ProgramParameter()

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

[Résolu] Problème avec l'utilisation de ProgramParameter()

Message par Octavius »

Bonjour,

J'ai un problème avec l'utilisation de ProgramParameter(). Je travaille sur un logiciel multilingue qui a pour but d'ouvrir les fichiers d'extension .txt.strings.bin (j'ai pas choisi l'extension).

Lorsque j'exécute mon éditeur et que j'ouvre normalement un fichier que j'ai choisi à partir du bouton "Ouvrir", tout se passe bien :
Image

Afin d'ouvrir automatiquement un fichier avec mon éditeur j'utilise ProgramParameter() pour récupérer le nom du fichier. Quand je fais un clic-droit sur un fichier, je vais dans "Ouvrir avec" et je choisi mon logiciel, là encore ça marche nickel.

Mais quand je fais un glisser-déposer, que je prends mon fichier dans l'explorateur windows et que je le dépose sur l'icône de mon exécutable, là ça me créé une confusion avec la langue (même si par ailleurs le fichier est lu correctement) et j'obtiens ça :
Image

La langue du logiciel est stocké dans un fichier au même format (.txt.strings.bin).

Pourriez-vous jeter un oeil à mon code pour me dire ce qui ne va pas avec le glisser-déposer ?

Code : Tout sélectionner

;Logiciel pour éditer les fichiers d'extension .txt.strings.bin dans M2TW
;Nécessite l'activation du support Unicode (options de compilateur)

;-Initializations

;{-Constantes

#Title="BinEditor v2.2"
#Status=0
#File=0
#Win=0
Enumeration ;Gadgets
  #Open
  #Import
  #Save
  #Export
  #AZ
  #ZA
  #Add
  #OK
  #Cancel
  #Mod
  #Suppr
  #Shift
  #List
  #In
  #Out
EndEnumeration

;}

;{-Démarrage

;Instruction pour le debogueur
EnableExplicit

;Procédures initiales
Declare OpenMsg()
Declare.s Msg(Text$) 
Declare Error(Text$)
Declare Info(Text$)
Declare Window(Title$)
Declare.s OpenNames(File$)
Declare.s ImportNames(File$)

;Procédures courantes
Declare.b Add(In$,Out$)
Declare SetGadgets(Option.b)
Declare SelectItem()

;Procédures finales
Declare SaveNames(File$)
Declare ExportNames(File$,Title$)

Structure name
  In$
  Out$
EndStructure

;Variables
Define File$,Text$,Descr$,Event.l,Item.l,State.b,*List.name
;Listes chaînées
Global NewList Names.name()
Global NewList MsgFile.name()

State=1

;}

;**********************************************************************************************************
;- > > Main window
;**********************************************************************************************************

OpenMsg()

If OpenWindow(#Win,0,0,510,350,#Title,#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
  ButtonGadget(#Open,10,10,90,25,Msg("BUTTON_OPEN"))
  ButtonGadget(#Import,10,45,90,25,Msg("BUTTON_IMPORT"))
  ButtonGadget(#Save,110,10,90,25,Msg("BUTTON_SAVE"))
  ButtonGadget(#Export,110,45,90,25,Msg("BUTTON_EXPORT"))
  ButtonGadget(#AZ,210,10,90,25,Msg("BUTTON_AZ"))
  ButtonGadget(#ZA,210,45,90,25,Msg("BUTTON_ZA"))
  ButtonGadget(#Add,310,10,90,25,Msg("BUTTON_ADD"))
  ButtonGadget(#OK,310,10,90,25,Msg("BUTTON_VALIDATE")) : HideGadget(#OK,1)
  ButtonGadget(#Cancel,310,45,90,25,Msg("BUTTON_CANCEL"))
  ButtonGadget(#Mod,410,10,90,25,Msg("BUTTON_MODIFY"))
  ButtonGadget(#Suppr,410,45,90,25,Msg("BUTTON_DELETE"))
  CheckBoxGadget(#Shift,440,80,60,20,Msg("CHECK_SHIFT"))
  ListViewGadget(#List,10,80,240,240)
  StringGadget(#In,260,80,170,20,"")
  EditorGadget(#Out,260,110,240,210) : SendMessage_(GadgetID(#Out),#EM_SETTARGETDEVICE,0,0)
  CreateStatusBar(#Status,WindowID(#Win))
EndIf

;Détection d'un paramètre
Text$=ProgramParameter()
If Text$<>""
  ;Ouverture automatique d'un fichier
  If GetExtensionPart(Text$)="bin"
    File$=OpenNames(Text$)
    SetGadgets(#True)
  ElseIf GetExtensionPart(Text$)="txt"
    File$=ImportNames(Text$)
    SetGadgets(#True)
  EndIf
Else
  SetGadgets(#False)
EndIf

;-Initial procedures
Procedure OpenMsg()
  Protected i.l,Length.l,Type.l,*Address,Number.l
  
  ;Initialisation et ouverture du fichier
  Type=-4
  Number=-5
  If Not ReadFile(#File,"bineditor.txt.strings.bin") : MessageRequester("Error!",#Title+" requires the language file 'bineditor.txt.strings.bin' to operate correctly !") : End : EndIf
  
  ;Boucle principale de lectu
  While Not Eof(#File)
    ;Longueur du mot à lire
    Length=ReadWord(#File)
    ;Nombre d'entités à lire
    If Type=-2 : Number=Length*2 : EndIf
    ;Si la longueur n'est pas nulle
    If Length
      If Type>-1
        ;Sélection du cas : In=0 et Out=1
        Select Type%2
          Case 0
            ;Ajoute un élément
            AddElement(MsgFile())
            ;Création de la chaîne de caractère et récupération de son adresse mémoire
            *Address=AllocateMemory(Length*2+1)
            ;Lecture de la chaîne de caractère
            ReadData(#File,*Address,Length*2)
            ;On met un zéro pour signaler la fin de la chaîne de caractère
            PokeW(*Address+Length*2,0)
            ;Stockage de la chaîne ainsi créée
            MsgFile()\In$=PeekS(*Address,Length*2+1,#PB_Unicode)            ;Libération de la mémoire temporaire
            FreeMemory(*Address)
          Case 1
            ;Même procédure que ci-dessus
            *Address=AllocateMemory(Length*2+1)
            ReadData(#File,*Address,Length*2)
            PokeW(*Address+Length*2,0)
            MsgFile()\Out$=PeekS(*Address,Length*2+1,#PB_Unicode)
            FreeMemory(*Address)
        EndSelect
      EndIf
    EndIf
    ;Incrémentation
    Type+1
    ;Fin de fichier
    If Type=Number : Break : EndIf
  Wend
  
  CloseFile(#File)
  
EndProcedure

Procedure.s Msg(Text$)
  ForEach MsgFile()
    If Text$=MsgFile()\In$
      ;La chaîne de caractère a été trouvée
      ProcedureReturn MsgFile()\Out$
    EndIf
  Next
  ;La chaîne de caractère est introuvable
  ProcedureReturn Text$
EndProcedure

Procedure Error(Text$)
  ;Avec icône rond rouge et croix blanche
  MessageRequester(Msg("WINDOW_ERROR"),Text$,16)
  End
EndProcedure

Procedure Info(Text$)
  ;Avec icône information
  MessageRequester(Msg("WINDOW_INFO"),Text$,64)
EndProcedure

Procedure.s OpenNames(File$)
  Protected i.l,Length.l,Type.l,*Address,Number.l
  
  If File$=""
    SetGadgets(#False)
    ProcedureReturn ""
  Else
    SetGadgets(#True)
  EndIf
  
  ;Initialisation et ouverture du fichier
  Type=-4
  Number=-5
  If Not ReadFile(#File,File$) : Error(Msg("ERROR_OPEN")) : EndIf
  
  ;Boucle principale de lecture
  While Not Eof(#File)
    ;Longueur du mot à lire
    Length=ReadWord(#File)
    ;Nombre d'entités à lire
    If Type=-2 : Number=Length*2 : EndIf
    ;Si la longueur n'est pas nulle
    If Length
      If Type>-1
        ;Sélection du cas : In=0 et Out=1
        Select Type%2
          Case 0
            ;Ajoute un élément
            AddElement(Names())
            ;Création de la chaîne de caractère et récupération de son adresse mémoire
            *Address=AllocateMemory(Length*2+1)
            ;Lecture de la chaîne de caractère
            ReadData(#File,*Address,Length*2)
            ;On met un zéro pour signaler la fin de la chaîne de caractère
            PokeW(*Address+Length*2,0)
            ;Stockage de la chaîne ainsi créée
            Names()\In$=PeekS(*Address,Length*2+1,#PB_Unicode)
            AddGadgetItem(#List,-1,Names()\In$)
            SetGadgetItemData(#List,CountGadgetItems(#List)-1,@Names())
            ;Libération de la mémoire temporaire
            FreeMemory(*Address)
          Case 1
            ;Même procédure que ci-dessus
            *Address=AllocateMemory(Length*2+1)
            ReadData(#File,*Address,Length*2)
            PokeW(*Address+Length*2,0)
            Names()\Out$=PeekS(*Address,Length*2+1,#PB_Unicode)
            FreeMemory(*Address)
        EndSelect
      EndIf
    EndIf
    ;Incrémentation
    Type+1
    ;Fin de fichier
    If Type=Number : Break : EndIf
  Wend
  
  CloseFile(#File)
  
  ProcedureReturn File$
  
EndProcedure

Procedure.s ImportNames(File$)
  Protected Com.l,Left.l,Right.l,Length.l,Type.b,String$,*Address
  
  If File$=""
    SetGadgets(#False)
    ProcedureReturn ""
  Else
    SetGadgets(#True)
  EndIf
  
  ;Ouverture du fichier spécifié
  If Not ReadFile(#File,File$) : Error(Msg("ERROR_IMPORT")) : EndIf
  
  ReadWord(#File)
  
  While Not Eof(#File)
    ;Lecture de la ligne
    String$=ReadString(#File,#PB_Unicode)
    ;Recherche des commentaires
    Com=FindString(String$,"¬",1)
    
    ;Suppression des commentaires
    If Com : String$=Left(String$,Com-1) : EndIf
    ;Si la chaîne est maintenant vidée, on passe à l'itération suivante
    If Trim(String$)="" : Continue : EndIf
    
    ;Recherche d'un nom interne
    Left=FindString(String$,"{",1)
    Right=FindString(String$,"}",Left)
    Length=Len(String$)
    
    ;Le nom interne
    If Left And Right
      ;On ajout un nouvel élément
      AddElement(Names())
      ;Le nom interne est entre les accolades
      Names()\In$=Mid(String$,Left+1,Right-Left-1)
      ;Le nom externe suit
      Names()\Out$=Right(String$,Length-Right)
      ;On ajoute l'élément à la liste du gadget
      AddGadgetItem(#List,-1,Names()\In$)
      SetGadgetItemData(#List,CountGadgetItems(#List)-1,@Names())
    Else
      Error("ERROR_CORRUPTED")
    EndIf
  Wend
  
  ;Fermeture du fichier
  CloseFile(#File)
  
  ProcedureReturn File$+".strings.bin"
  
EndProcedure

;-Current procedures

Procedure.b Add(In$,Out$)
  ForEach Names()
    If Names()\In$=In$
      ProcedureReturn #False
    EndIf
  Next
  AddElement(Names())
  Names()\In$=In$
  Names()\Out$=Out$
  AddGadgetItem(#List,-1,Names()\In$)
  SetGadgetItemData(#List,CountGadgetItems(#List)-1,@Names())
  SetGadgetState(#List,CountGadgetItems(#List)-1)
  ProcedureReturn #True
EndProcedure

Procedure SetGadgets(Option.b)
  DisableGadget(#Mod,1)
  DisableGadget(#Suppr,1)
  DisableGadget(#In,1)
  DisableGadget(#Cancel,1)
  If Option
    DisableGadget(#Add,0)
    DisableGadget(#Save,0)
    DisableGadget(#List,0)
    DisableGadget(#Out,0)
    DisableGadget(#Export,0)
    DisableGadget(#AZ,0)
    DisableGadget(#ZA,0)
  Else
    DisableGadget(#Add,1)
    DisableGadget(#Save,1)
    DisableGadget(#List,1)
    DisableGadget(#Out,1)
    DisableGadget(#Export,1)
    DisableGadget(#AZ,1)
    DisableGadget(#ZA,1)
  EndIf
EndProcedure

Procedure SelectItem()
  Protected *List.name
  
  If GetGadgetState(#List)<>-1
    *List=GetGadgetItemData(#List,GetGadgetState(#List))
    SetGadgetText(#In,*List\In$)
    SetGadgetText(#Out,*List\Out$)
    DisableGadget(#Mod,0)
    DisableGadget(#Suppr,0)
  Else
    SetGadgetText(#In,"")
    SetGadgetText(#Out,"")
    DisableGadget(#Mod,1)
    DisableGadget(#Suppr,1)
  EndIf
EndProcedure

;-Final procedures

Procedure SaveNames(File$)
  Protected i.l,Length.l,String$,*Address,Number.l
  
  ;Création du fichier
  CreateFile(#File,File$)
  
  ;Entête du fichier
  WriteWord(#File,2)
  WriteWord(#File,2048)
  WriteWord(#File,ListSize(Names()))
  WriteWord(#File,0)
  
  ;Boucle d'écriture
  ForEach Names()
    
    ;Ecriture du nom interne
    String$=Names()\In$
    Length=Len(String$)*2
    *Address=@String$
    WriteWord(#File,Length/2)
    WriteData(#File,*Address,Length)
    
    ;Ecriture du nom externe
    String$=Names()\Out$
    Length=Len(String$)*2
    *Address=@String$
    WriteWord(#File,Length/2)
    WriteData(#File,*Address,Length)
    
  Next
  
  ;Zéro de fin de fichier
  WriteWord(#File,0)
  
  ;Clôture du fichier
  CloseFile(#File)
  
  ;Information
  Info(Msg("INFO_SUCCESS"))
  
EndProcedure

Procedure ExportNames(File$,Title$)
  
  ;Création du fichier texte
  CreateFile(#File,Left(File$,Len(File$)-12))
  
  ;Entête
  WriteWord(#File,-257)
  WriteStringN(#File,"¬ Generated by "+Title$,#PB_Unicode)
  
  ;Boucle principale d'écriture
  ForEach Names()
    WriteStringN(#File,"{"+Names()\In$+"}"+Names()\Out$,#PB_Unicode)
  Next
  
  ;Fermeture du fichier
  CloseFile(#File)
  
  ;Information
  Info(Msg("INFO_SUCCESS"))
  
EndProcedure

;**********************************************************************************************************
;- > > Main loop
;**********************************************************************************************************

Repeat
  
  ;En attente d'un événement
  Event=WaitWindowEvent()
  
  Select Event
    Case #PB_Event_Gadget
      Event=EventGadget()
      Select Event
        
        Case #Open
          If File$=""
            Text$=GetCurrentDirectory()
          Else
            Text$=GetPathPart(File$)
          EndIf
          File$=OpenFileRequester(Msg("WINDOW_OPEN"),Text$,Msg("FILE_STRINGS")+" (*.txt.strings.bin)|*.txt.strings.bin",0)
          ;Màj du statut
          SetWindowTitle(#Win,#Title)
          StatusBarText(#Status,0,Msg("STATUS_LOAD"))
          ;Nettoyage
          ClearGadgetItems(#List)
          ClearList(Names())
          File$=OpenNames(File$)
          ;Nettoyage des champs
          SetGadgetText(#In,"")
          SetGadgetText(#Out,"")
          StatusBarText(#Status,0,"")
          
        Case #Import
          If File$=""
            Text$=GetCurrentDirectory()
          Else
            Text$=GetPathPart(File$)
          EndIf
          File$=OpenFileRequester(Msg("WINDOW_IMPORT"),Text$,Msg("FILE_TEXT")+" (*.txt)|*.txt",0)
          ;Màj du statut
          SetWindowTitle(#Win,#Title)
          StatusBarText(#Status,0,Msg("STATUS_IMPORT"))
          ;Nettoyage
          ClearGadgetItems(#List)
          ClearList(Names())
          File$=ImportNames(File$)
          ;Nettoyage des champs
          SetGadgetText(#In,"")
          SetGadgetText(#Out,"")
          StatusBarText(#Status,0,"")
        
        Case #Save
          Text$=SaveFileRequester(Msg("WINDOW_SAVE"),File$,Msg("FILE_STRINGS")+"(*.txt.strings.bin)|*.txt.strings.bin",0)
          If Text$<>""
            If Right(Text$,4)=".bin"
              File$=Text$
            Else
              File$=Text$+".bin"
            EndIf
            ;Màj du statut
            StatusBarText(#Status,0,Msg("STATUS_SAVE"))
            ;Procédure de sauvegarde
            SaveNames(File$)
            StatusBarText(#Status,0,"")
            SetWindowTitle(#Win,#Title)
          EndIf
          
        Case #Export
          Text$=SaveFileRequester(Msg("WINDOW_EXPORT"),Left(File$,Len(File$)-12),Msg("FILE_TEXT")+" (*.txt)|*.txt",0)
          If Text$<>""
            If Right(Text$,4)=".txt"
              File$=Text$+".strings.bin"
            Else
              File$=Text$+".txt.strings.bin"
            EndIf
            ;Màj du statut
            StatusBarText(#Status,0,Msg("STATUS_EXPORT"))
            ExportNames(File$,#Title)
            StatusBarText(#Status,0,"")
          EndIf
          
        Case #AZ,#ZA
          Item=GetGadgetItemData(#List,GetGadgetState(#List))
          ClearGadgetItems(#List)
          SortStructuredList(Names(),Event-#AZ,OffsetOf(name\In$),#PB_Sort_String)
          ForEach Names()
            AddGadgetItem(#List,-1,Names()\In$)
            SetGadgetItemData(#List,CountGadgetItems(#List)-1,@Names())
            If Item=@Names() : SetGadgetState(#List,CountGadgetItems(#List)-1) : EndIf
          Next
          SelectItem()
          
        Case #Add
          ;Modification de l'interface
          HideGadget(#OK,0)
          HideGadget(#Add,1)
          Setgadgets(#False)
          DisableGadget(#Open,1)
          DisableGadget(#Import,1)
          DisableGadget(#Cancel,0)
          DisableGadget(#In,0)
          DisableGadget(#Out,0)
          SetGadgetText(#In,"")
          SetGadgetText(#Out,"")
          SetGadgetState(#List,CountGadgetItems(#List)-1)
          State=0
          
        Case #OK
          Text$=GetGadgetText(#In)
          Descr$=GetGadgetText(#Out)
          If Text$<>""
            StatusBarText(#Status,0,Msg("STATUS_ADD"))
            If Add(Text$,Descr$)
              SetWindowTitle(#Win,#Title+"*")
              ;Nettoyage des champs
              SetGadgetText(#In,"")
              SetGadgetText(#Out,"")
            Else
              Info(Msg("INFO_ENTRY"))
            EndIf
            StatusBarText(#Status,0,"")
          EndIf
          
        Case #Cancel
          ;Modification de l'interface
          HideGadget(#OK,1)
          HideGadget(#Add,0)
          DisableGadget(#Open,0)
          DisableGadget(#Import,0)
          SetGadgets(#True)
          SelectItem()
          State=1
          
        Case #Mod
          If GetGadgetState(#List)<>-1
            SetWindowTitle(#Win,#Title+"*")
            StatusBarText(#Status,0,Msg("STATUS_MODIFY"))
            ;Procédure de modification
            *List=GetGadgetItemData(#List,GetGadgetState(#List))
            *List\Out$=GetGadgetText(#Out)
            StatusBarText(#Status,0,"")
          EndIf
          
        Case #Suppr
          If GetGadgetState(#List)<>-1
            SetWindowTitle(#Win,#Title+"*")
            StatusBarText(#Status,0,Msg("STATUS_DELETE"))
            ;Procédure de suppression
            Item=GetGadgetState(#List)
            ChangeCurrentElement(Names(),GetGadgetItemData(#List,Item))
            DeleteElement(Names())
            RemoveGadgetItem(#List,Item)
            If Item>=CountGadgetItems(#List) : Item-1 : EndIf
            SetGadgetState(#List,Item)
            SelectItem()
            ;Nettoyage des champs
            StatusBarText(#Status,0,"")
          EndIf
          
        Case #Shift
          Text$=GetGadgetText(#In)
          If GetGadgetState(#Shift)
            StringGadget(#In,260,80,170,20,Text$,#PB_String_UpperCase)
          Else
            StringGadget(#In,260,80,170,20,Text$)
          EndIf
          DisableGadget(#In,State)
          
        Case #List : SelectItem()
          
      EndSelect
    Case #PB_Event_CloseWindow
      End
  EndSelect
  
ForEver
N'oubliez de télécharger le fichier de langue française, absolument nécessaire à l'exécution du code : http://keonet.free.fr/bineditor.txt.strings.bin (2 Ko)
Vous pouvez vous servir de ce même fichier pour tester l'éditeur.
Dernière modification par Octavius le ven. 23/oct./2009 10:34, modifié 1 fois.
Cls
Messages : 620
Inscription : mer. 22/juin/2005 8:51
Localisation : Nantes

Re: Problème avec l'utilisation de ProgramParameter()

Message par Cls »

A première vue, il y a un bug dans PB.

J'ai ajouté ce code avant le OpenMsg() :

Code : Tout sélectionner

MessageRequester("", ProgramFilename())
SetCurrentDirectory(ProgramFilename())
MessageRequester("", GetCurrentDirectory())
Le résultat est différent quand on l'ouvre en double cliquant et quand on fait un glisser/déposer ! Étonnant...

Une solution peut être de définir manuellement un répertoire de travail.
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Re: Problème avec l'utilisation de ProgramParameter()

Message par Octavius »

Cette partie code n'est pas bonne :

Code : Tout sélectionner

SetCurrentDirectory(ProgramFilename())
Ca devrait plutôt être :

Code : Tout sélectionner

SetCurrentDirectory(GetPathPart(ProgramFilename()))
Si j'insère cette dernière ligne avant OpenMsg() ça marche ! Merci Cls, je ne pensais pas qu'on trouverait la solution aussi rapidement !

Je ne sais pas si c'est un bug de PB, en tout cas il semble que le glisser-déposer spécifie un autre dossier courant que quand on fait "ouvrir avec", bizarre !
Cls
Messages : 620
Inscription : mer. 22/juin/2005 8:51
Localisation : Nantes

Re: Problème avec l'utilisation de ProgramParameter()

Message par Cls »

Oula oui exact ! J'ai zappé le

Code : Tout sélectionner

GetPathPart()
:oops:
Je suis malade en ce moment alors faut pas m'en vouloir ! :roll:
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Problème avec l'utilisation de ProgramParameter()

Message par Backup »

signale que ton probleme est résolu, par un [Résolu] dans le titre du sujet.. ;)


ps : pour modifier le titre il te faut éditer le Premier message de ton topic ....
Répondre