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 :
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 :
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
Vous pouvez vous servir de ce même fichier pour tester l'éditeur.