COMポートを検索するには?

解決


ひろ  2002-08-02 12:59:45  No: 104616  IP: [192.*.*.*]

こんにちは。よろしくお願いします。

今、MSCommを使って通信をしているのですが、
COMポートの設定は「 MSComm1.CommPort = 6 」とか
すると思うのですが、ポートナンバーが分かっていないとき、
あるいは他の人の環境で使いたいときは、エラーになってしまうので、
そのPCが今使えるCOMポートを検索できない
ものかと思っています。コンボボックスなどで
あらかじめ使えるCOMポートを表示できたら便利かと。
どうしたらそのような機能が付けられるか、
教えていただけないでしょうか。
お願いします。

編集 削除
あんちゃん  2002-08-02 15:26:25  No: 104617  IP: [192.*.*.*]

APIのCreateFile関数の戻り値(−1以外)で判別可能だと思います。

COMポート番号は1〜16まで設定可能ですが、
MSCommではアプリケーションが動作するシステムに存在しない
COMポート番号指定でエラーが発生するのは仕様上、仕方ないかと思います。

無理やり調べるとしたら、Resume Nextでエラーを無視するのも1つの手段だと思いますが、動作上保証できないかと思います。

編集 削除
あんちゃん  2002-08-02 16:18:15  No: 104618  IP: [192.*.*.*]

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

編集 削除
ひろ  2002-08-02 18:03:33  No: 104619  IP: [192.*.*.*]

あんちゃんさんご返答ありがとうございます。

書いていただいたソースを私の環境でも実行してみました。
うまくいきました!ありがとうございます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
*************************************************

編集 削除
あんちゃん  2002-08-02 18:51:26  No: 104620  IP: [192.*.*.*]

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度しか動いていないようです。

編集 削除
あんちゃん  2002-08-02 19:21:36  No: 104621  IP: [192.*.*.*]

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

編集 削除
あんちゃん  2002-08-02 19:32:23  No: 104622  IP: [192.*.*.*]

>>確認済(手書きで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の違いで動かないかもしれないので変更して確かめる。

編集 削除
ひろ  2002-08-02 22:46:16  No: 104623  IP: [192.*.*.*]

あんちゃんさん何度も丁寧にありがとうございますm(__)m

しかし、APIの宣言を手書きとは凄いですね。
とりあえず頼まれた仕事ですので、最終確認はこちらの環境では
週明けにならないとできないのですが、恐らくあんちゃんさんの
教えていただいた通りにやればいけると思います。

Const GENERIC_READ = &H80000000
Const GENERIC_WRITE = &H40000000
Const OPEN_EXISTING = 3

とか、VBを始めたばかりでまだ何をやっているのかよく分かりませんが、
もっと勉強していきたいと思います。
本当にありがとうございましたm(__)m

編集 削除