Registre Windows - Modifier une donnée

Sujets variés concernant le développement en PureBasic
PureDev
Messages : 31
Inscription : sam. 25/janv./2014 9:42

Registre Windows - Modifier une donnée

Message par PureDev »

Bonjour. Je sollicite à nouveau votre aide efficace.

Action attendue :
Cahier des charges
Modifier à partir de PureBasic une valeur de la base de registre.
J'ai fait l'acquisition de deux voix françaises chez IVONA (Céline et Matthieu).
Je souhaite alterner dans une application PureBasic l'emploi de ces deux voix.
Une façon souple et légère consiste à changer une donnée de la base de registre comme le fait le panneau "Propriétés de la synthèse vocale".

Méthode utilisée :
Pour utiliser la voix masculine:
Global Chemin$ = GetCurrentDirectory()
Procedure Matthieu ()
Matthieu=RunProgram(Chemin$ + "ChangerVoix\BatMatthieu.bat","","")
RunProgram(Chemin$ + "ChangerVoix\Exit.bat","","")
EndProcedure


Pour utiliser la voix féminine:
Global Chemin$ = GetCurrentDirectory()
Procedure Celine ()
RunProgram(Chemin$ + "ChangerVoix\BatCéline.bat","","")
RunProgram(Chemin$ + "ChangerVoix\Exit.bat","","")
EndProcedure

Ces deux procédures lance respectivement un fichier batch:
Pour la voix Céline, le fichier nommé BatCéline.bat contient:

REG ADD HKCU\Software\Microsoft\Speech\Voices /v DefaultTokenID /t REG_SZ /f /d "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\IVONA 2 Voice Celine22"

Pour la voix Matthieu, le fichier BatMatthieu.bat contient:

REG ADD HKCU\Software\Microsoft\Speech\Voices /v DefaultTokenID /t REG_SZ /f /d "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\IVONA 2 Voice Mathieu22"

Le fichier Exit.bat contient simplement :
exit

A l'appel de l'une ou l'autre des ces deux procédures, l'invite de commande est ouverte, et apparaît à l'écran durant une durée variant d'une fraction de seconde jusqu'à 2 ou 3 secondes. Le changement de voix est parfaitement obtenu. Donc l'objectif est atteint. Ce qui ne ma plait pas, c'est l'apparition de la fenêtre noire de l'invite de commande du plus mauvais effet.

Pour pallier cet inconvénient, j'ai ajouter à la fin de RunProgram l'option #PB_Program_Hide, exemple :

Matthieu=RunProgram(Chemin$ + "ChangerVoix\BatMatthieu.bat","","",#PB_Program_Hide)

En espérant cacher l'invite de commande. mais dans ce cas la commande RunProgram n'exécute pas le changement de voix, et ceci sans message d'erreur. Mon application reste sur la même voix, quelque soit la procédure appelée.
J'ai modifié les paramètres de l'invite de commande (taille, position, couleur de fond, police.....). Mais RunProgram appelle toujours la même fenêtre noire, dont la position est aléatoire à l'écran.

Un autre moyen:
En espérant trouver une solution, j'ai tenté de mettre en oeuvre RunProgram en appelant cmd.exe, avec passage de paramètre :
RunProgram("cmd.exe","dir *.*","") pour faire un essai. Mais le passage de paramètre n'est pas effectué.

Ma demande:
Pouvez vous m'aider soit en améliorant la première solution (appel de l'une ou l'autre procédure, sans apparition de l'invite de commande), soit en en m'indiquant comment la deuxième solution (lancer cmd.exe avec passage de paramètre)?
Enfin, il existe peut être une autre solution permettant de modifier la base de registre sans passer par l'invite de commande. J'ai cherché une procédure sans trouver dans le forum.

D'avance merci.
Mesa
Messages : 1097
Inscription : mer. 14/sept./2011 16:59

Re: Registre Windows - Modifier une donnée

Message par Mesa »

Pour la base de registre il me semble que la droopylib sait le faire : http://droopylib.pagesperso-orange.fr/

Code : Tout sélectionner

RegSetValue(Key.s, ValueName.s, Value.s, Type, ComputerName.s) 



--------------------------------------------------------------------------------

Description : Sets a Value
Type can be #REG_SZ / #REG_DWORD / #REG_BINARY / #REG_EXPAND_SZ
For REG_BINARY type use Hexa value as String
Returns 1 if successful or 0 if it fails


--------------------------------------------------------------------------------

Source : 
ProcedureDLL RegSetValue(Key.s, ValueName.s, Value.s, Type, ComputerName.s) ; Sets a Value
  
  
  Shared RegWow64.l,RegEx,topKey,KeyName.s
  RegConvertRegKeyToTopKeyAndKeyName(Key)
  
  If ComputerName = "."
    If RegEx
      GetHandle = RegOpenKeyEx_(topKey,KeyName,0,#KEY_ALL_ACCESS|RegWow64,@hKey) 
    Else
      GetHandle = RegOpenKey_(topKey,KeyName,@hKey) 
    EndIf
  Else 
    lReturnCode = RegConnectRegistry_(ComputerName,topKey,@lhRemoteRegistry) 
    If RegEx
      GetHandle = RegOpenKeyEx_(lhRemoteRegistry,KeyName,0,#KEY_ALL_ACCESS|RegWow64,@hKey) 
    Else
      GetHandle = RegOpenKey_(lhRemoteRegistry,KeyName,@hKey) 
    EndIf
  EndIf 
  
  If GetHandle = #ERROR_SUCCESS 
    lpcbData = 255 
    lpData.s = Space(255) 
    
    Select Type 
        
      Case #REG_EXPAND_SZ 
        CompilerIf #PB_Compiler_Unicode 
          GetHandle = RegSetValueEx_(hKey, ValueName, 0, #REG_EXPAND_SZ, @Value, Len(Value)*2 + 1) 
        CompilerElse
          GetHandle = RegSetValueEx_(hKey, ValueName, 0, #REG_EXPAND_SZ, @Value, Len(Value) + 1) 
        CompilerEndIf
        
      Case #REG_SZ
        CompilerIf #PB_Compiler_Unicode 
          GetHandle = RegSetValueEx_(hKey, ValueName, 0, #REG_SZ, @Value, Len(Value)*2 + 1) 
        CompilerElse
          GetHandle = RegSetValueEx_(hKey, ValueName, 0, #REG_SZ, @Value, Len(Value) + 1) 
        CompilerEndIf
        
      Case #REG_DWORD 
        lValue = Val(Value) 
        GetHandle = RegSetValueEx_(hKey, ValueName, 0, #REG_DWORD, @lValue, 4) 
        
      Case #REG_BINARY
        LenBuffer=Len(Value)/2
        *RegBuffer=AllocateMemory(LenBuffer)
        For n=0 To LenBuffer-1
          OctetHexa.s=Mid(Value,(n*2)+1,2)
          Octet=Val("$"+OctetHexa)
          PokeB(*RegBuffer+n,Octet)
        Next
        GetHandle= RegSetValueEx_(hKey,ValueName,0,#REG_BINARY,*RegBuffer,LenBuffer) 
        FreeMemory(*RegBuffer)
        
    EndSelect 
    
    RegCloseKey_(hKey) 
    ergebnis = 1 
    ProcedureReturn ergebnis 
  Else 
    RegCloseKey_(hKey) 
    ergebnis = 0 
    ProcedureReturn ergebnis 
  EndIf 
EndProcedure 
Il semble aussi que la manipulation de la base de registre est difficile car elle diffère en fonction de win8 et w7 et moins et il faut se méfier des versions 64b et 32b de Windows.

Il y a u module ici
http://www.purebasic.fr/english/viewtop ... 12&t=56204

Sinon, j'ai trouvé ça quelque part dans un forum (marche bien sous Xp32b=pas de fenêtre noir)

Code : Tout sélectionner

prog$="c:\ok.bat"
	;prog$="ping.exe"
	
	prg=RunProgram(prog$, "",".",#PB_Program_Hide|#PB_Program_Open|#PB_Program_Read|#PB_Program_Write)
	;prg=RunProgram("ping.exe", "www.purebasic.fr",".",#PB_Program_Hide|#PB_Program_Open|#PB_Program_Read|#PB_Program_Write)
  ;prg=RunProgram(prog$, "www.purebasic.fr",".",30)
	
	s_asci$=Space(64000)
	
	Debug prg
	If prg
	  s_asci$=ReadProgramString(prg)
	  OemToChar_(@s_asci$,@s_asci$)
	  Debug  s_asci$
	  While ProgramRunning(prg)
	    s_asci$ =ReadProgramString(prg)
	    OemToChar_(@s_asci$,@s_asci$)
	    Debug s_asci$
	  Wend
	EndIf
M.
PureDev
Messages : 31
Inscription : sam. 25/janv./2014 9:42

Re: Registre Windows - Modifier une donnée

Message par PureDev »

Merci de m'avoir répondu et mis sur la piste de la solution.

En fait, il fallait mettre l'ensemble suivant:

#PB_Program_Hide|#PB_Program_Open|#PB_Program_Read|#PB_Program_Write

en option à Runprogram et non pas seulement #PB_Program_Hide comme je l'avais tenté.

Maintenant la commande des voix est assurée, et l'invite de commande n'apparaît plus.

Encore merci Mesa.L'efficacité de ce forum est encore démontré.
Répondre