basamir
Messages postés335Date d'inscriptionvendredi 21 octobre 2005StatutMembreDernière intervention 8 mars 2008
-
14 mai 2007 à 16:33
basamir
Messages postés335Date d'inscriptionvendredi 21 octobre 2005StatutMembreDernière intervention 8 mars 2008
-
20 mai 2007 à 00:53
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?
cs_Nicko11
Messages postés1141Date d'inscriptionmercredi 7 mars 2007StatutMembreDernière intervention19 septembre 20073 16 mai 2007 à 13:55
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 ?
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 19 mai 2007 à 11:26
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
Vous n’avez pas trouvé la réponse que vous recherchez ?
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 19 mai 2007 à 14:09
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...
basamir
Messages postés335Date d'inscriptionvendredi 21 octobre 2005StatutMembreDernière intervention 8 mars 2008 19 mai 2007 à 14:19
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
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 19 mai 2007 à 14:29
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...)
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 19 mai 2007 à 14:33
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..
basamir
Messages postés335Date d'inscriptionvendredi 21 octobre 2005StatutMembreDernière intervention 8 mars 2008 19 mai 2007 à 14:48
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.
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 19 mai 2007 à 14:57
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
basamir
Messages postés335Date d'inscriptionvendredi 21 octobre 2005StatutMembreDernière intervention 8 mars 2008 19 mai 2007 à 15:15
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.
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 19 mai 2007 à 15:30
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 ...)
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 19 mai 2007 à 15:35
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
basamir
Messages postés335Date d'inscriptionvendredi 21 octobre 2005StatutMembreDernière intervention 8 mars 2008 19 mai 2007 à 15:40
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.
basamir
Messages postés335Date d'inscriptionvendredi 21 octobre 2005StatutMembreDernière intervention 8 mars 2008 19 mai 2007 à 15:42
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
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 19 mai 2007 à 15:52
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
basamir
Messages postés335Date d'inscriptionvendredi 21 octobre 2005StatutMembreDernière intervention 8 mars 2008 20 mai 2007 à 00:53
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.