こんにちは。よろしくお願いします。
今、MSCommを使って通信をしているのですが、
COMポートの設定は「 MSComm1.CommPort = 6 」とか
すると思うのですが、ポートナンバーが分かっていないとき、
あるいは他の人の環境で使いたいときは、エラーになってしまうので、
そのPCが今使えるCOMポートを検索できない
ものかと思っています。コンボボックスなどで
あらかじめ使えるCOMポートを表示できたら便利かと。
どうしたらそのような機能が付けられるか、
教えていただけないでしょうか。
お願いします。
APIのCreateFile関数の戻り値(−1以外)で判別可能だと思います。
COMポート番号は1〜16まで設定可能ですが、
MSCommではアプリケーションが動作するシステムに存在しない
COMポート番号指定でエラーが発生するのは仕様上、仕方ないかと思います。
無理やり調べるとしたら、Resume Nextでエラーを無視するのも1つの手段だと思いますが、動作上保証できないかと思います。
MSCommの例(動作確認済)
On Error Resume Next
Dim I_COM As Integer
For I_COM = 1 To 16
MSComm1.CommPort = I_COM
MSComm1.Settings = "9600,N,8,1"
MSComm1.PortOpen = True
If MSComm1.PortOpen = True Then
List1.AddItem ("COM_" & I_COM & " OK")
Else
List1.AddItem ("COM_" & I_COM & " NG")
End If
MSComm1.PortOpen = False
Next
あんちゃんさんご返答ありがとうございます。
書いていただいたソースを私の環境でも実行してみました。
うまくいきました!ありがとうございますm(__)m
質問なのですが、例えばCOMポートが2つ以上持っている人が
このプログラムを実行させた場合はどうなるのでしょうか?
MSCommというのは必ず1つを選んでくれるものなのでしょうか?
それから、CreateFile関数でも実験してみました。
Declareなどはサンプルを流用したので大丈夫だと思いますが、
素人の私が書いた方の分岐が問題なんです(^_^;)
以下のように書いてみたのですが、何故かうまく動きません・・・。
もしお分かりになるようでしたら教えていただけませんか?
よろしくお願いいたします。
*************************************************
cnt = 1
For i = 0 To 15
comname = "COM" & cnt
hComm = CreateFile(comname, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
cnt = cnt + 1
If hComm <> -1 Then
strcom = comoname & vbCr
End If
Next
If strcom = "" Then
MsgBox "現在使用できるポートがありません"
Else
MsgBox strcom
End If
*************************************************
MSCommのプログラムはCOMが複数(2個…こちらの環境)あるものでも動きます。
実行結果
COM_1 OK
COM_2 OK
COM_3 NG
COM_4 NG
・
・
・
COM_16 NG
1つだけ選ぶ理由として
MSComm1.CommPort = I_COM
MSComm1.PortOpen = True
の2行を参考にしてください。
CreateFile関数ですが
For文が使われていないのが気になります。
それによってcntも1度しか動いていないようです。
CreateFileを認識してくれないので何ともいえないけど
Dim I_COM As Integer
Dim comname As String
Dim hComm As Long
For I_COM = 1 To 16
comname = "COM" & I_COM
hComm = CreateFile(comname, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
If hComm <> -1 Then
List1.AddItem ("COM_" & I_COM & " OK")
Else
List1.AddItem ("COM_" & I_COM & " NG")
End If
Next
>>確認済(手書きでAPI宣言すると上手くいかないねぇ)
APIで引っかかるとしたら
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" _
(ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long
Const GENERIC_READ = &H80000000
Const GENERIC_WRITE = &H40000000
Const OPEN_EXISTING = 3
PublicかPrivateの違いで動かないかもしれないので変更して確かめる。
あんちゃんさん何度も丁寧にありがとうございますm(__)m
しかし、APIの宣言を手書きとは凄いですね。
とりあえず頼まれた仕事ですので、最終確認はこちらの環境では
週明けにならないとできないのですが、恐らくあんちゃんさんの
教えていただいた通りにやればいけると思います。
Const GENERIC_READ = &H80000000
Const GENERIC_WRITE = &H40000000
Const OPEN_EXISTING = 3
とか、VBを始めたばかりでまだ何をやっているのかよく分かりませんが、
もっと勉強していきたいと思います。
本当にありがとうございましたm(__)m