Basic Univers
; Permet la communication entre deux processus via un pipe
;   Ce dernier utilise la fonction ReadFile de l'API Windows
; Contient le code serveur et le code client.

; Procédure :
  ; 1) Lancer le serveur
  ; 2) Créer un pipe nommé
  ; 3) Lancer le client
  ; 4) Envoyer des messages


; ------------------------------------------------------------
;- Code Serveur


#PIPE_ACCES_DUPLEX = 3
#Gadget = 0

Global Buffer_Ecriture.s, Buffer_Lecture.s, Envoie
Buffer_Ecriture = Space(100)
Buffer_Lecture = Space(100)


Procedure Thread_Client(pipe.l)
  fConnected = ConnectNamedPipe_(pipe, #Null)
  If fConnected
    AddGadgetItem(#Gadget, - 1, "Un client est connecté")
  EndIf
 
  ReadFile_(pipe, @Buffer_Lecture, Len(Buffer_Lecture), @recu, 0)
  AddGadgetItem(#Gadget, - 1, Buffer_Lecture)
 
  Buffer_Ecriture = "Le serveur vous a déconnecté"
  WriteFile_(pipe, Buffer_Ecriture, Len(Buffer_Ecriture), @envoye, 0)

  FlushFileBuffers_(pipe)
   
  If DisconnectNamedPipe_(pipe)
    AddGadgetItem(#Gadget, - 1, "Le server est en attente de connexion client")
  EndIf
   Thread_Client(pipe.l)
EndProcedure


If OpenWindow(0, 0, 0, 600, 200, #PB_Window_SystemMenu|#PB_Window_ScreenCentered, "Server Pipe Nommé") And CreateGadgetList(WindowID(0))
  EditorGadget(#Gadget, 10, 10, 580, 160, #PB_Container_Raised)
  If CreateMenu(0, WindowID())
    MenuTitle("Action")
    MenuItem( 1, "Créer un pipe nommé")
    MenuItem( 2, "Quitter")
  EndIf
 
  Repeat
    EventID.l = WaitWindowEvent()
    Select EventID
      Case #PB_EventMenu
        Select EventMenuID()
          Case 1
            Hpipe = CreateNamedPipe_("\\.\pipe\NomDePipe", #PIPE_ACCES_DUPLEX, #PIPE_TYPE_MESSAGE | #PIPE_READMODE_MESSAGE, 1, 100, 100, 3000, #Null)
            If Hpipe
              AddGadgetItem(#Gadget, - 1, "Le server est en attente de connexion client")
              Thread = CreateThread(@Thread_Client(), Hpipe)
            EndIf
             
          Case 2
            Quit = 1
        EndSelect
       
      Case #PB_Event_CloseWindow
        KillThread(Thread)
        CloseHandle_(Hpipe)
      Quit = 1
    EndSelect
   
  Until Quit = 1
EndIf




; ------------------------------------------------------------
;- Code Client


#Gadget = 0

Global Hpipe
Global Buffer_Ecriture.s, Buffer_Lecture.s
Buffer_Ecriture = Space(100)
Buffer_Lecture = Space(100)

Procedure AppelServer(Texte.s)
lpszPipename.s = GetGadgetText(3)
 
result = WaitNamedPipe_(lpszPipename, 3000)

Hpipe = CreateFile_( lpszPipename, #GENERIC_READ |#GENERIC_WRITE, 0, #Null, #OPEN_EXISTING, 0, #Null)

If Hpipe
  Buffer_Ecriture.s = Texte
  WriteFile_(Hpipe, Buffer_Ecriture, @Len(Buffer_Ecriture), @envoye, 0)
  FlushFileBuffers_(Hpipe)
 
  ReadFile_(Hpipe, @Buffer_Lecture, Len(Buffer_Lecture), @recu, 0)
  AddGadgetItem(#Gadget, - 1, Buffer_Lecture)
EndIf
 
CloseHandle_(Hpipe)
EndProcedure

If OpenWindow(0, 0, 0, 600, 200, #PB_Window_SystemMenu|#PB_Window_ScreenCentered, "Client Pipe Nommé") And CreateGadgetList(WindowID(0))
  EditorGadget(#Gadget, 10, 60, 580, 120, #PB_Container_Raised)
  StringGadget(1, 10, 36, 400, 20, "Client: Voici un message")
  ButtonGadget(2, 460, 36, 100, 20, "Envoyer")
  StringGadget(3, 10, 10, 400, 20, "\\.\pipe\NomDePipe")
  TextGadget(4, 420, 10, 180, 20, "Nom du serveur (Par défaut local ici)")
    Repeat
      EventID.l = WaitWindowEvent()
      Select EventID
        Case #PB_EventGadget
          Select EventGadgetID()
            Case 2
              AppelServer(GetGadgetText(1))
          EndSelect
         
        Case #PB_Event_CloseWindow
          Quit = 1
      EndSelect
 
    Until Quit = 1
EndIf