KeyboardInkey() pour la saisie de données .... ou pas !

Programmation avancée de jeux en PureBasic
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

KeyboardInkey() pour la saisie de données .... ou pas !

Message par falsam »

Suite à un réponse que j'ai donnée sur ce post J'ai extrait ce code d'une application client/serveur 2D qui n'a jamais vu le jour à part trois quatre membres de ce forum.

L'utilisateur saisie un message qui sera affiché sur son screen et envoyé à un serveur qui lui même l'enverra aux autres client.

■ Contraintes:
- La saisie du message sera traitée avec la fonction KeyboardInkey()
- Le message envoyé avec la touche Entrée KeyboardReleased(#PB_Key_Return)
- La correction arrière d'un caractère avec la touche BackSpace KeyboardReleased(#PB_Key_Back)
- Le premier caractère sera toujours en majuscule.
- Le curseur de saisie clignotera.
- Les accents circonflexes seront traités.
- Les messages affichés à l’écran s'estompent du plus ancien ou plus récent.
- Je ne traiterais pas de l'envoie au serveur.

■ Code

Code : Tout sélectionner

EnableExplicit

Enumeration Font
  #FontApp
  #FontMessage
EndEnumeration

Structure NewSprite
  id.i 
  x.i
  y.i
  opacity.f
  text.s
EndStructure
Global NewList UserMessages.NewSprite()

Global Buffer.s, Character.s
Global ScreenBackground = RGB(75, 0, 130)
Global StringBackground = RGB(128, 128, 128)
Global FontColor = RGB(255, 255, 255)
Global CursorToken = 1, CursorTimer = 0, CursorColor 
Global Circumflex.b


Declare Start()
Declare MessageInsert(UserMessage.s)
Declare MessageDisplay()
Declare onTimer()

Start()

Procedure Start()
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  ;Font des messages affichés
  LoadFont(#FontMessage, "", 11)
  
  OpenWindow(0, 0, 0, 0, 0, "FullScreen", #PB_Window_BorderLess | #PB_Window_Maximize)
  
  ;Timer de gestion du curseur (500 ms)
  AddWindowTimer(0, CursorTimer, 500)
  BindEvent(#PB_Event_Timer, @onTimer(), 0, CursorTimer)
  
  OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0))
  
  ;Message de bienvenue
  MessageInsert("Welcome, Bienvenue ....")
  MessageInsert("Enter your message and press the enter key")
  MessageInsert("Escape key to exit")
  
  ;Boucle
  Repeat
    Repeat : Until WindowEvent() = 0
    
    ClearScreen(ScreenBackground)
    ExamineKeyboard()
    
    If KeyboardReleased(#PB_Key_Return)
      If Len(buffer) <> 0
        MessageInsert(Buffer)
        Buffer = ""
      EndIf
          
    ElseIf KeyboardReleased(#PB_Key_Back)
      Buffer = Left(Buffer, Len(Buffer)-1)
      
    Else
      Character = KeyboardInkey()
      
      ;Traitement de l'accent circonflex
      If Asc(Character) = 24158
        Circumflex = #True
      EndIf
            
      ;Les caractéres à controler.
      If FindString("1234567890 @/?,;.!:()éàèâêîôûç'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", Character)        
        
        ;Traitement de l'accent circonflexe
        If Circumflex 
          Select Character
            Case "a" : Character = "â"
            Case "e" : Character = "ê"
            Case "i" : Character = "î"
            Case "o" : Character = "ô"
            Case "u" : Character = "û"  
          EndSelect
          Circumflex = #False
        EndIf
        
        ;Le premier caractére sera en majuscule
        If Len(Buffer) = 0
          Buffer + UCase(Character)
        Else
          Buffer + Character  
        EndIf
      EndIf
    EndIf 
    
    ;Dessin de la zone de saisie
    If StartDrawing(ScreenOutput())
      RoundBox(20, ScreenHeight() - 50, ScreenWidth() - 60, 30, 4, 4, RGB(128, 128, 128))
      DrawingMode(#PB_2DDrawing_Transparent)
      FrontColor(FontColor)
      DrawText(25, ScreenHeight() - 45, Buffer)
      DrawText(25 + TextWidth(Buffer), ScreenHeight() - 45, "|", CursorColor)
      StopDrawing()
    EndIf
    
    ;Affichage des messages
    MessageDisplay()
    
    FlipBuffers()
  Until KeyboardReleased(#PB_Key_Escape)
EndProcedure

;Ajout d'un message dans la pile des messages à afficher à l'écran
Procedure MessageInsert(UserMessage.s)
  
  ;Ajout du message
  AddElement(UserMessages())
  UserMessages()\text = UserMessage
  
  ;Création du sprite correspondant au message 
  UserMessages()\id = CreateSprite(-1, ScreenWidth(), 24, #PB_Sprite_AlphaBlending)
  UserMessages()\x = 20
  UserMessages()\y = 50
  UserMessages()\opacity = 255
  
  If StartDrawing(SpriteOutput(UserMessages()\id))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Box(0, 0, ScreenWidth(), 24, RGBA(0, 0, 0, 0))
    DrawingFont(FontID(#FontMessage))
    DrawText(0, 0, UserMessages()\text, RGBA(255, 255, 255, 255), RGBA(0, 0, 0, 0))
    StopDrawing()  
  EndIf
EndProcedure

;Affichage de la pile de messages
Procedure MessageDisplay()
  ForEach UserMessages()
    
    ;Affichage du message 
    UserMessages()\y = (ScreenHeight() - 24 * (ListSize(UserMessages()) - ListIndex(UserMessages()))) - 70
    UserMessages()\opacity - 0.2  
    DisplayTransparentSprite(UserMessages()\id, UserMessages()\x , UserMessages()\y , UserMessages()\opacity)
    
    ;Suppression du message si transparent
    If UserMessages()\opacity < 0
      FreeSprite(UserMessages()\id)
      DeleteElement(UserMessages())
    EndIf
  Next
EndProcedure

Procedure onTimer()
  CursorToken * -1
  If CursorToken = 1
    CursorColor = FontColor
  Else
    CursorColor = StringBackground
  EndIf   
EndProcedure
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: KeyboardInkey() pour la saisie de données

Message par Fig »

Très bien ce code...
Par contre ça coince parfois, notamment les '?' par exemple.
Mais pour la saisie de peu de texte c'est très pratique. :idea:
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: KeyboardInkey() pour la saisie de données

Message par falsam »

Fig a écrit :Par contre ça coince parfois, notamment les '?' par exemple.
Voir réponse http://www.purebasic.fr/french/viewtopi ... 59#p194659
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: KeyboardInkey() pour la saisie de données

Message par falsam »

Le string caché.

Principe : Se servir d'un StringGadget caché est n'acceptant qu'un seul caractère.

La touches Entrée ainsi que la touche Escape sont gérées comme un événement window au lieu d'un événement screen.
La touche BackSpace permet d'effacer un ou plusieurs caractères. Le premier caractére est effacé. La répétition intervient pour les suivants aprés la mise en place d'un timer.
A des fins de test, vous pouvez déplacer une raquette avec les flèches gauche et droite du clavier.

Voici le code

Code : Tout sélectionner

  EnableExplicit
  
  Enumeration Font
    #FontApp
    #FontMessage
  EndEnumeration
  
  Enumeration Window
    #mf  
  EndEnumeration
  
  Enumeration Gadget
    #Character
  EndEnumeration
  
  Enumeration Shorcut
    #Key_Enter  
    #Key_Esc
  EndEnumeration
  
  Enumeration Timer
    #T0 ;Clignotement du curseur
    #T1 ;BackSpace
  EndEnumeration
    
  Structure NewSprite
    id.i 
    x.i
    y.i
    opacity.f
    text.s
  EndStructure
  Global NewList UserMessages.NewSprite()
  
  Global Buffer.s
  Global ScreenBackground = RGB(75, 0, 130)
  Global StringBackground = RGB(128, 128, 128)
  Global FontColor = RGB(255, 255, 255)
  Global CursorToken = 1, CursorColor 
  Global BackSpaceToken
  
  Declare Start()
  Declare MessageUpdate()               ;Mise à jour du buffer de saisie
  Declare MessageControl()              ;Controle du buffer se saisie avant envoi
  Declare MessageInsert(UserMessage.s)  ;Ajout d'un message dans la pile des messages à afficher à l'écran
  Declare MessageDisplay()              ;Affichage de la pile de messages
  Declare onTimer()                     ;Clignotement du cursor
  Declare Exit()
  
  Start()
  
  Procedure Start()
    Protected Racket, RacketX, RacketY
    
    InitSprite()
    InitKeyboard()
    InitMouse()
    
    ;Font des messages affichés
    LoadFont(#FontMessage, "", 11)
    
    OpenWindow(#mf, 0, 0, 0, 0, "Chat 2D ", #PB_Window_BorderLess | #PB_Window_Maximize)
    
    ;StringGadget caché comme support de saisie d'un caractérer unique    
    StringGadget(#Character, 0, 0, 0, 0, "")
    SetActiveGadget(#Character)
    SetGadgetAttribute(#Character, #PB_String_MaximumLength, 1)
    AddKeyboardShortcut(#mf, #PB_Shortcut_Return, #Key_Enter)  
    AddKeyboardShortcut(#mf, #PB_Shortcut_Escape, #Key_Esc)  
    
    ;Timer de gestion du curseur (500 ms)
    AddWindowTimer(#mf, #T0, 500)
    
    ;Déclencheurs evenementiels
    BindGadgetEvent(#Character, @MessageUpdate(), #PB_EventType_Change)
    BindEvent(#PB_Event_Menu, @MessageControl(), #mf, #Key_Enter)
    BindEvent(#PB_Event_Menu, @Exit(), #mf, #Key_Esc)
    BindEvent(#PB_Event_Timer, @onTimer(), #mf, #T0)
    
    ;[2D]
    OpenWindowedScreen(WindowID(#mf), 0, 0, WindowWidth(#mf), WindowHeight(#mf))
    
    ;Création d'un sprite (par exemple un raquette de tir)
    Racket = CreateSprite(-1, 100, 20)
    RacketX = (ScreenWidth() - 50)/2
    RacketY = ScreenHeight() - 100  
    
    ;Message de bienvenue
    MessageInsert("Welcome, Bienvenue ....")
    MessageInsert("Enter your message and press the enter key")
    MessageInsert(Chr($2190) + " And " + Chr($2192) + " move your racket")
    MessageInsert("Escape key to exit")
    
    ;Boucle evenementielle
    Repeat
      Repeat : Until WindowEvent() = 0
      
      ClearScreen(ScreenBackground)      
      
      ExamineKeyboard()
      ExamineMouse()
      
      ;L'utilisateur presse la touche BackSpace 
      ;BackSpaceToken = 0   => Effacer le caractere et déclencher le timer
      ;BackSpaceToken > 1   => Ne rien faire
      ;BackSpaceToken >= 2  => BackSpace continu 
      If KeyboardPushed(#PB_Key_Back)
        If BackSpaceToken = 0
          BackSpaceToken = 1
          AddWindowTimer(#mf, #T1, 400)   
          BindEvent(#PB_Event_Timer, @onTimer(), #mf, #T1)
          Buffer = Left(Buffer, Len(Buffer)-1)
        EndIf 
        If BackSpaceToken >= 2
          Buffer = Left(Buffer, Len(Buffer)-1)
        EndIf          
      EndIf          
      
      ;L'utilisateur a relaché la touche BackSpace
      ;Reset de BackSpaceToken et desactivation du timer
      If KeyboardReleased(#PB_Key_Back)
        BackSpaceToken = 0
        UnbindEvent(#PB_Event_Timer, @onTimer(), #mf, #T1)
      EndIf
      
      ;Déplacement de la raquette (Il s'agitr d'un test)
      If KeyboardPushed(#PB_Key_Left) And RacketX > 5  
        RacketX - 10
      EndIf          
      
      If KeyboardPushed(#PB_Key_Right)  And RacketX < ScreenWidth() - SpriteWidth(Racket)  
        RacketX + 10
      EndIf          
      
      DisplaySprite(Racket, RacketX , RacketY)

      
      ;Dessin de la zone de saisie 
      If StartDrawing(ScreenOutput())
        RoundBox(20, ScreenHeight() - 50, ScreenWidth() - 60, 30, 4, 4, RGB(128, 128, 128))
        DrawingMode(#PB_2DDrawing_Transparent)
        FrontColor(FontColor)
        DrawText(25, ScreenHeight() - 45, Buffer)
        DrawText(25 + TextWidth(Buffer), ScreenHeight() - 45, "|", CursorColor)
        StopDrawing()
      EndIf
      
      ;Affichage des messages
      MessageDisplay()
      
      FlipBuffers()
    ForEver 
  EndProcedure
  
  ;Mise à jour du buffer de saisie
  Procedure MessageUpdate()
    Buffer + GetGadgetText(#Character)
    If Len(Buffer) = 1
      Buffer = UCase(Buffer)
    EndIf
    SetGadgetText(#Character, "")
  EndProcedure
  
  ;Controle du buffer se saisie avant envoi
  Procedure MessageControl()
    If Len(Trim(Buffer)) <> 0
      MessageInsert(Buffer)
      Buffer = ""
    EndIf
  EndProcedure
  
  ;Ajout d'un message dans la pile des messages à afficher à l'écran
  Procedure MessageInsert(UserMessage.s)
    
    ;Ajout du message
    AddElement(UserMessages())
    UserMessages()\text = UserMessage
    
    ;Création du sprite correspondant au message 
    UserMessages()\id = CreateSprite(-1, ScreenWidth(), 24, #PB_Sprite_AlphaBlending)
    UserMessages()\x = 20
    UserMessages()\y = 50
    UserMessages()\opacity = 255
    
    If StartDrawing(SpriteOutput(UserMessages()\id))
      DrawingMode(#PB_2DDrawing_AllChannels)
      Box(0, 0, ScreenWidth(), 24, RGBA(0, 0, 0, 0))
      DrawingFont(FontID(#FontMessage))
      DrawText(0, 0, UserMessages()\text, RGBA(255, 255, 255, 255), RGBA(0, 0, 0, 0))
      StopDrawing()  
    EndIf
  EndProcedure
  
  ;Affichage de la pile de messages
  Procedure MessageDisplay()
    ForEach UserMessages()
      
      ;Affichage du message 
      UserMessages()\y = (ScreenHeight() - 24 * (ListSize(UserMessages()) - ListIndex(UserMessages()))) - 70
      UserMessages()\opacity - 0.2  
      DisplayTransparentSprite(UserMessages()\id, UserMessages()\x , UserMessages()\y , UserMessages()\opacity)
      
      ;Suppression du message si transparent
      If UserMessages()\opacity < 0
        FreeSprite(UserMessages()\id)
        DeleteElement(UserMessages())
      EndIf
    Next
  EndProcedure
  
  ;Clignotement du curseur
  Procedure onTimer()
    Select EventTimer()
      Case #T0
        CursorToken * -1
        If CursorToken = 1
          CursorColor = FontColor
        Else
          CursorColor = StringBackground
        EndIf
        
      Case #T1 ;Active ou désactive la touche BackSpace
        BackSpaceToken + 1
    EndSelect
  EndProcedure
    
  Procedure Exit()
    End  
  EndProcedure
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: KeyboardInkey() pour la saisie de données .... ou pas !

Message par Fig »

C'est parfait ça ! Juste à gérer l'effacement avec une tempo...

(personnellement je préfère les strings apparents, mais bon...) Image
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: KeyboardInkey() pour la saisie de données .... ou pas !

Message par falsam »

Fig a écrit :Juste à gérer l'effacement avec une tempo...
Voila qui est fait. Le code précédent est modifié.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Mesa
Messages : 1093
Inscription : mer. 14/sept./2011 16:59

Re: KeyboardInkey() pour la saisie de données .... ou pas !

Message par Mesa »

J'ai accéléré le code (sur mon pc en tout cas) en optimisant le code.

- En général et avec un screen en particulier, mettre la boucle principale dans une procédure ralentit beaucoup le processus, sans en connaître la raison.

- Utiliser des variable définies une fois pour toute plutôt que d'utiliser les procédures de type rgba(), etc gagne pas mal de temps aussi, surtout depuis windows 10 qui, sauf erreur, utilise un émulateur pour ce genre de procedure quand elles viennent de l'api win32. Et je crois que purebasic n'utilise que ces api là, pas les api win10

- utiliser ElapsedMilliseconds() plutôt qu'un timer

- comme le screen est réaffiché en permanence, pas besoin d'effacer le curseur, il s'efface "tout seul"

(Sur mon pc, je n'ai ps de problème de '?')

M.

Code : Tout sélectionner

; EnableExplicit

Enumeration Font
	#FontApp
	#FontMessage
EndEnumeration

Structure NewSprite
	id.i 
	x.i
	y.i
	opacity.f
	text.s
EndStructure
Global NewList UserMessages.NewSprite()

Global Buffer.s, Character.s
Global ScreenBackground = RGB(75, 0, 130)
Global StringBackground = RGB(128, 128, 128)
Global FontColor = RGB(255, 255, 255)
Global CursorToken = 1, CursorTimer = 0, CursorColor 
Global Circumflex.b


; Declare Start()
Declare MessageInsert(UserMessage.s)
Declare MessageDisplay()
; Declare onTimer()

Procedure Timer( Milliseconds ) 
	Static Delay, Result 
	If Delay = #False :Delay = ElapsedMilliseconds() :EndIf 
	If ((ElapsedMilliseconds() - Delay) >= (Milliseconds*2))  
		Delay = 0  
		Result ! 1 
	EndIf 
	ProcedureReturn Result 
EndProcedure 

; Start()

; Procedure Start()

;====> En général et avec un screen en particulier, mettre la boucle principale dans une procédure
; ralentit beaucoup le processus.





InitSprite()
InitKeyboard()
InitMouse()


;Font des messages affichés
LoadFont(#FontMessage, "", 11)

OpenWindow(0, 0, 0, 0, 0, "FullScreen", #PB_Window_BorderLess | #PB_Window_Maximize)

;Timer de gestion du curseur (500 ms)
;   AddWindowTimer(0, CursorTimer, 500)
;   BindEvent(#PB_Event_Timer, @onTimer(), 0, CursorTimer)

OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0))
Global sw0=ScreenWidth()
Global sh0=ScreenHeight()
Global sh=ScreenHeight() - 50
Global sw= ScreenWidth() - 60
Global cs= RGB(128, 128, 128)
Global sht=ScreenHeight() - 45
Global rgba255=RGBA(255, 255, 255, 255)
Global rgba0=RGBA(0, 0, 0, 0)

KeyboardMode(#PB_Keyboard_International  )
;Message de bienvenue
MessageInsert("Welcome, Bienvenue ....")
MessageInsert("Enter your message and press the enter key")
MessageInsert("Escape key to exit")

;Boucle
Repeat
	Repeat : Until WindowEvent() = 0
	
	ClearScreen(ScreenBackground)
	ExamineKeyboard()
	
	If KeyboardReleased(#PB_Key_Return)
		If Len(buffer) <> 0
			MessageInsert(Buffer)
			Buffer = ""
		EndIf
		
	ElseIf KeyboardReleased(#PB_Key_Back)
		Buffer = Left(Buffer, Len(Buffer)-1)
		
	Else
		Character = KeyboardInkey()
		
		;Traitement de l'accent circonflex
		If Asc(Character) = 24158;221;
			Circumflex = #True
		EndIf
		
		;Les caractéres à controler.
		If FindString("1234567890 @/?,;.!:()éàèâêîôûç'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", Character)        
			
			;Traitement de l'accent circonflexe
			If Circumflex 
				Select Character
					Case "a" : Character = "â"
					Case "e" : Character = "ê"
					Case "i" : Character = "î"
					Case "o" : Character = "ô"
					Case "u" : Character = "û"  
				EndSelect
				Circumflex = #False
			EndIf
			
			;Le premier caractére sera en majuscule
			If Len(Buffer) = 0
				Buffer + UCase(Character)
			Else
				Buffer + Character  
			EndIf
		EndIf
	EndIf 
	
	;Dessin de la zone de saisie
	If StartDrawing(ScreenOutput())
		RoundBox(20, sh, sw, 30, 4, 4, cs)
		DrawingMode(#PB_2DDrawing_Transparent)
		FrontColor(FontColor)
		DrawText(25, sht, Buffer)
		
		If Timer( 300 ) 
			DrawText(25 + TextWidth(Buffer), sht, "|", FontColor)
		EndIf
		
		StopDrawing()
	EndIf
	
	;Affichage des messages
	MessageDisplay()
	
	FlipBuffers()
Until KeyboardReleased(#PB_Key_Escape)
; EndProcedure

;Ajout d'un message dans la pile des messages à afficher à l'écran
Procedure MessageInsert(UserMessage.s)
	
	;Ajout du message
	AddElement(UserMessages())
	UserMessages()\text = UserMessage
	
	;Création du sprite correspondant au message 
	UserMessages()\id = CreateSprite(-1, sw0, 24, #PB_Sprite_AlphaBlending)
	UserMessages()\x = 20
	UserMessages()\y = 50
	UserMessages()\opacity = 255
	
	If StartDrawing(SpriteOutput(UserMessages()\id))
		DrawingMode(#PB_2DDrawing_AllChannels)
		Box(0, 0, sw0, 24, rgba0)
		DrawingFont(FontID(#FontMessage))
		DrawText(0, 0, UserMessages()\text, rgba255, rgba0)
		StopDrawing()  
	EndIf
EndProcedure

;Affichage de la pile de messages
Procedure MessageDisplay()
	ForEach UserMessages()
		
		;Affichage du message 
		UserMessages()\y = (sh0 - 24 * (ListSize(UserMessages()) - ListIndex(UserMessages()))) - 70
		UserMessages()\opacity - 0.2  
		DisplayTransparentSprite(UserMessages()\id, UserMessages()\x , UserMessages()\y , UserMessages()\opacity)
		
		;Suppression du message si transparent
		If UserMessages()\opacity < 0
			FreeSprite(UserMessages()\id)
			DeleteElement(UserMessages())
		EndIf
	Next
EndProcedure

; Procedure onTimer()
;   CursorToken * -1
;   If CursorToken = 1
;     CursorColor = FontColor
;   Else
;     CursorColor = StringBackground
;   EndIf   
; EndProcedure
Répondre