Choix du port Com par une optionbox

Signaler
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008
-
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008
-
bonjour,

mon application devrait écrire sur 3 à 4 ports séries différents, à cet effet, je dois avoir 3 à 4 zones de choix sous forme de frame pour choisir le numéro de ports Com de chaque sortie, est ce que celà est faisable par optionbox?

Merci

40 réponses

Messages postés
1141
Date d'inscription
mercredi 7 mars 2007
Statut
Membre
Dernière intervention
19 septembre 2007
3
Une idée me vient, n'est il pas possible que ton erreur vienne du fait que je le buffer de reception ou de transmission soit plein et que donc le chngement de port COM soit impossible ?
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008

je ne crois pas mais je vais me tacher à faire une rotine si cela est possible de vider le tampon !

Merci pour ton soucis Nicko11
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008

ça ne marche toujours pas???
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
27
Bonjour basamir,
Tu as là de quoi travailler proprement :
Analyses et adapte :


Private Type PORT_INFO_2
    pPortName As String
    pMonitorName As String
    pDescription As String
    fPortType As Long
    Reserved As Long
End Type
Private Type API_PORT_INFO_2
    pPortName As Long
    pMonitorName As Long
    pDescription As Long
    fPortType As Long
    Reserved As Long
End Type
Private Declare Function EnumPorts Lib "winspool.drv" Alias "EnumPortsA" (ByVal pName As String, ByVal Level As Long, ByVal lpbPorts As Long, ByVal cbBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (pTo As Any, uFrom As Any, ByVal lSize As Long)
Private Declare Function HeapAlloc Lib "kernel32" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GetProcessHeap Lib "kernel32" () As Long
Private Declare Function HeapFree Lib "kernel32" (ByVal hHeap As Long, ByVal dwFlags As Long, lpMem As Any) As Long
Dim Ports(0 To 100) As PORT_INFO_2
Public Function TrimStr(strName As String) As String
    Dim x As Integer
    x = InStr(strName, vbNullChar)    If x > 0 Then TrimStr Left(strName, x - 1) Else TrimStr strName
End Function
Public Function LPSTRtoSTRING(ByVal lngPointer As Long) As String
    Dim lngLength As Long
    lngLength = lstrlenW(lngPointer) * 2
    LPSTRtoSTRING = String(lngLength, 0)
    CopyMem ByVal StrPtr(LPSTRtoSTRING), ByVal lngPointer, lngLength
    LPSTRtoSTRING = TrimStr(StrConv(LPSTRtoSTRING, vbUnicode))
End Function
Public Function GetAvailablePorts(ServerName As String) As Long
    Dim ret As Long
    Dim PortsStruct(0 To 100) As API_PORT_INFO_2
    Dim pcbNeeded As Long
    Dim pcReturned As Long
    Dim TempBuff As Long
    Dim i As Integer
    ret = EnumPorts(ServerName, 2, TempBuff, 0, pcbNeeded, pcReturned)
    TempBuff = HeapAlloc(GetProcessHeap(), 0, pcbNeeded)
    ret = EnumPorts(ServerName, 2, TempBuff, pcbNeeded, pcbNeeded, pcReturned)
    If ret Then
        CopyMem PortsStruct(0), ByVal TempBuff, pcbNeeded
        For i = 0 To pcReturned - 1
            Ports(i).pDescription = LPSTRtoSTRING(PortsStruct(i).pDescription)
            Ports(i).pPortName = LPSTRtoSTRING(PortsStruct(i).pPortName)
            Ports(i).pMonitorName = LPSTRtoSTRING(PortsStruct(i).pMonitorName)
            Ports(i).fPortType = PortsStruct(i).fPortType
        Next
    End If
    GetAvailablePorts = pcReturned
    If TempBuff Then HeapFree GetProcessHeap(), 0, TempBuff
End Function
Private Sub Form_Activate()
    Dim NumPorts As Long
    Dim i As Integer
    ' ici, j'ai mis "", ce qui conduit à la recherche des ports sur le PC local
    ' pour rechercher sur un serveur distant, j'aurais mis  "//nom_du_serveur"
    NumPorts = GetAvailablePorts("")
    Me.AutoRedraw = True
    For i = 0 To NumPorts - 1
        If UCase(Left(Ports(i).pPortName, 3)) = "COM" Then
          If Not IsNumeric(Right(Ports(i).pPortName, 1)) Then
            Ports(i).pPortName = Mid(Ports(i).pPortName, 1, Len(Ports(i).pPortName) - 1)
          End If
          Combo1.AddItem Ports(i).pPortName
        End If
    Next
    Combo1.ListIndex = 0
End Sub


Private Sub Command1_Click()
  nomport = Combo1.Text
  numeroport = Val(Mid(Combo1.Text, 4))
  MSComm1.CommPort = numeroport
  MsgBox "nom du port choisi " & nomport & vbCrLf & "numéro du port " & numeroport
  ' voilà donc
  ' si maintenant (par exemple avec un contôle MScomm, tu dois te référer à un
  'numéro de port, c'est de numeroport qu'il faut te servir
  'exemple :MSComm1.CommPort = numeroport
End Sub


 
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
27
Si, maintenant, tu tiens absolument à laisser le choix du port par l'intermédiaire de boutons radios (optionButtons), on peut le faire (légère vtransformation) mais je ne te le conseille pas car ilo faudra alors : 1) prévoir la création dynamique de contrôles optionbuttons en fonction du nombre de ports trouvé et 2) occuper sur ta form une surface proportionnelle à ce nombre, ce qui risque fort d'être fâcheux.
Mais tu dis...
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008

je ne te cache pas que tu utilise les API mais moi je ne pige absolument rien et je ne sais pas où mettre chaque partie de ton code là?
je suis navré de te deranger comme ça
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008

beh en fait mon souci c'est que je dois avoir trois combo pour permettre aux utilisateurs de choisir pour chaque type de communication un port com.

car mon application doit communiquer avec trois systèmes différents.

je viens de tester ton code il est magnifique mais comment le modifier pour trois combo dans la même page?
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
27
Bon...
On va t'aider à comprendre, alors...
Fais un petit projet tout neuf :
Une Form Form1
et dessus :
Une ComboBox Combo1
et
un bouton de commande Command1

tu lances...
tu cliques (sélectionnes, donc) un élément de ta ComboBox
puis tu cliques sur le bouton Command1, pour voir...
Te sera affiché : le Nom et le N+ d'un des ports COM disponibles sur ta machine (et donc à utiliser dans ton code d'instructions de communications).
Vas-y et observe bien (rien ne tombe tout rôti du ciel...)
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
27
Pouyr 3 combos sur la même page ?
Fastoche : tu en fais trois !
Mais je ne vois pas pourquoi il en faudrait 3 ! (l'utilisateur fait de toute façon un choix de port com en cliquant.... et c'est ce port choisi qui sera utilisé pour la communication à établir...)
Quel est donc le problème auquel tu es confronté... on le résoudra si tu en expliques parfaitement les tenants et les aboutissants..
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008

ok,

je m'explique:
mon application doit communiquer avec un autre logiciel via les DDE, chose que j'ai réussi à faire et récupère une chaîne de caractère sous forme numerique. Ensuite il doit écrire cette valeur dans un port com que l'utilisateur doit choisir librement, puis il doit choisir un autre (biensur la machine est équipé de minimum 3 ports COM) pour qu'un autre logiciel (hyperterminal p.e) puisse lire cette valeur (on doit relier les deux coms jusque la choisi par un cable modem null) un troisième port com pour écrire cette meme valeur sur un afficheur externe pour que tout le monde puisse voir cette valeur.

Est ce que je suis clair?

Merci pout ton aide
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
27
Ce n'est pas vraiment clair, mais celà ne fait rien ...
Je suppose que si l'utilisateur a choisi un port Com pour une opération, il ne doit pas pouvoir l'utiliser pour l'une des 2 autres ?
Est-celà ?
Si oui... je te fabrique un truc pour y parvenir... (ce ne doit pas être bien difficile)..
Dis-nous
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008

exactement,
une fois un com x est choisi pour une sortie, il ne doit pas etre opérationnel pour les 2 qui reste.

Je récap afin de mieux m'expliquer:
sur mon application j'ai ma page principale où j'affiche la valeur reçu de l'autre application en fait c'est un poids en Kg.
il y a deux façon de faire:
1° méthode:
Avoir trois frames dans la page principale dont la visibilité est false pour que seul l'admin puisse les afficher pour paramétrer les ports com ainsi que la trame à écrire sur chaque port choisi.
dans le menu, on donne la main à l'admin d'afficher ces trois frames dont chacun dispose d'un combobox pour choisir le port qu'il désire.

2° Méthode:
dans la page principale, on ouvre une autre page de config qui est équipée de trois frames aussi (la même chose koi).

Avec les deux solutions, une fois le choix est fait pour les trois com ainsi que les trames de sorties, celui ci (le choix) doit être sauvegardé avec getsettings afin que lors d'un autre démarage de l'applic les coms sont préalablement choisis.

J'espère que la situation est plus claire?

Merci
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
27
Laisse pour l'instant tes méthodes...
On va y aller à l'économe (je suis corse à moitié et donc très fainéant...)

Tu vas me préparer un petit projet tout neuf dans lequel :
- sur la Form Form 1

    - un bouton de commande appelé "DEMARRAGE"
    - un cadre "Frame" appelé Frame1
         - dans ce cadre :
             - une ComboBox appelée Combo1
              - un bouton de Commande appelé OPERATIONS
              - un bouton de commande appelé ANNULER

Quand tu es prêt, tu dis ( je commence à coder).
 Fais vite car je devrai m'en aller dans 30 minutes, mais c'est largement suffisant.
Je t'attends (fissa, alors, hein ...)
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008

ok c'est fait
vas y je t'en prie
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
27
OK,

Tu vas voir comme le vieux travaille vite  :

Private numeroop As Integer
Private Type PORT_INFO_2
    pPortName As String
    pMonitorName As String
    pDescription As String
    fPortType As Long
    Reserved As Long
End Type
Private Type API_PORT_INFO_2
    pPortName As Long
    pMonitorName As Long
    pDescription As Long
    fPortType As Long
    Reserved As Long
End Type
Private Declare Function EnumPorts Lib "winspool.drv" Alias "EnumPortsA" (ByVal pName As String, ByVal Level As Long, ByVal lpbPorts As Long, ByVal cbBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (pTo As Any, uFrom As Any, ByVal lSize As Long)
Private Declare Function HeapAlloc Lib "kernel32" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GetProcessHeap Lib "kernel32" () As Long
Private Declare Function HeapFree Lib "kernel32" (ByVal hHeap As Long, ByVal dwFlags As Long, lpMem As Any) As Long
Dim Ports(0 To 100) As PORT_INFO_2
Public Function TrimStr(strName As String) As String
    Dim x As Integer
    x = InStr(strName, vbNullChar)    If x > 0 Then TrimStr Left(strName, x - 1) Else TrimStr strName
End Function
Public Function LPSTRtoSTRING(ByVal lngPointer As Long) As String
    Dim lngLength As Long
    lngLength = lstrlenW(lngPointer) * 2
    LPSTRtoSTRING = String(lngLength, 0)
    CopyMem ByVal StrPtr(LPSTRtoSTRING), ByVal lngPointer, lngLength
    LPSTRtoSTRING = TrimStr(StrConv(LPSTRtoSTRING, vbUnicode))
End Function
Public Function GetAvailablePorts(ServerName As String) As Long
    Dim ret As Long
    Dim PortsStruct(0 To 100) As API_PORT_INFO_2
    Dim pcbNeeded As Long
    Dim pcReturned As Long
    Dim TempBuff As Long
    Dim i As Integer
    ret = EnumPorts(ServerName, 2, TempBuff, 0, pcbNeeded, pcReturned)
    TempBuff = HeapAlloc(GetProcessHeap(), 0, pcbNeeded)
    ret = EnumPorts(ServerName, 2, TempBuff, pcbNeeded, pcbNeeded, pcReturned)
    If ret Then
        CopyMem PortsStruct(0), ByVal TempBuff, pcbNeeded
        For i = 0 To pcReturned - 1
            Ports(i).pDescription = LPSTRtoSTRING(PortsStruct(i).pDescription)
            Ports(i).pPortName = LPSTRtoSTRING(PortsStruct(i).pPortName)
            Ports(i).pMonitorName = LPSTRtoSTRING(PortsStruct(i).pMonitorName)
            Ports(i).fPortType = PortsStruct(i).fPortType
        Next
    End If
    GetAvailablePorts = pcReturned
    If TempBuff Then HeapFree GetProcessHeap(), 0, TempBuff
End Function


Private Sub Command1_Click()
 
End Sub


Private Sub ANNULER_Click()
  numeroop = 0
  Frame1.Visible = False
  DEMARRAGE.Visible = True
End Sub


Private Sub Form_Activate()
  Frame1.Visible = False
End Sub


Private Sub OPERATIONS_Click()
  nomport = Combo1.Text
  numeroport = Val(Mid(Combo1.Text, 4))
  MSComm1.CommPort = numeroport
  MsgBox "nom du port choisi " & nomport & vbCrLf & "numéro du port " & numeroport
  Combo1.RemoveItem Combo1.ListIndex
  Combo1.ListIndex = 0
 
  ' c'est ici que tu envoies vers ta routine de communication adéquate, en fonction de numeroop et en donnant comme 'paramètre numeroport
 
  numeroop = numeroop + 1
  OPERATIONS.Caption = "opération" & numeroop
  If numeroop > 3 Then
     Frame1.Visible = False
     numeroop = 0
     DEMARRAGE.Visible = True
  End If
End Sub


Private Sub DEMARRAGE_Click()
   numeroop = numeroop + 1
   Combo1.Clear
   Dim NumPorts As Long
    Dim i As Integer
    ' ici, j'ai mis "", ce qui conduit à la recherche des ports sur le PC local
    ' pour rechercher sur un serveur distant, j'aurais mis  "//nom_du_serveur"
    NumPorts = GetAvailablePorts("")
    Me.AutoRedraw = True
    For i = 0 To NumPorts - 1
        If UCase(Left(Ports(i).pPortName, 3)) = "COM" Then
          If Not IsNumeric(Right(Ports(i).pPortName, 1)) Then
            Ports(i).pPortName = Mid(Ports(i).pPortName, 1, Len(Ports(i).pPortName) - 1)
          End If
          Combo1.AddItem Ports(i).pPortName
        End If
    Next
    Combo1.ListIndex = 0
    OPERATIONS.Caption = "opération" & numeroop
    ANNULER.Caption = "ANNULER"
    Frame1.Visible = True
    DEMARRAGE.Visible = False
End Sub

Essaye ...
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008

oui j'ai déjà essayé ton code est ça marche
ça n'affiche que les ports com dispo sur ma machine et quand je choisi un le msgbox m'affiche lequel est choisi.
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008

mais j'ai pas bien saisi ce que je dois mettre là où t'as mis ce commentaire:
  ' c'est ici que tu envoies vers ta routine de communication adéquate, en fonction de numeroop et en donnant comme 'paramètre numeroport

!!
Merci
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
27
Ben ...
Fastoche, non ?
Tu as là, à chaque opération (opération1, iperation2 et opération3) le choix d'un numeroport.
Tu connais également le numero de l'opération (numeroop)

Que te reste-t-il à faire à ce niveau ?
Tout simplement, par exemple, ouvrir un select Case
Select case numeroop
   Case  1
       - tes instruction relatives à l'exécution de la 1ère communication sur le N° de port (numeroport) sélectionné
  Case 2
       - tes instruction relatives à l'exécution de la 2ème communication sur le N° de port (numeroport) sélectionné
  Case 3 
      - tes instruction relatives à l'exécution de la 3ème communication sur le N° de port (numeroport) sélectionné
End Select

Encore que personnellement, je pointerais plutôt vers une sous-routine à laquelle je passerais en paramètres les variables numeroop et numeroport (uniquement pour faciliter la maintenance car le résultat serait le même.

C'est maintenant à toi de faire un peu joujou, maintenant (ton travail est là super mâché).
Je vais maintenant voir la mer et empoisonner la vie de mes amis pêcheurs.
Bon travail
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008

Merci 1001 une fois mon ami
bonne regolade
Messages postés
335
Date d'inscription
vendredi 21 octobre 2005
Statut
Membre
Dernière intervention
8 mars 2008

bonsoir,
ton code est bon mais je ne sais pas pourqoui ça n'affecte pas les ports série, meme si je choisi COM3 par exemple, je teste avec hyperterminal qui est configuré avec com2 et j'ai la trame qui passe par com2 sachat que j'ai choisi Com3 et je suis certaine que c'est le com3.

bizare non?