BCB6.0でのCOM設定方法

このQ&Aのポイント
  • BCB初心者なので、BCBを使用してシリアル通信を行なっています。COM設定が不定な状態で使用することになり、設定できるようにしたのですがエラーが発生してしまいます。
  • 現在のコードでは、ポートの開閉に関する処理が行われていますが、エラーが発生しています。
  • また、COMポートの設定に関する部分でもエラーが発生しており、デバッガ例外が発生しています。
回答を見る
  • ベストアンサー

BCB6.0でのCOM設定方法

BCB初心者なのですが、BCBを使用してシリアル通信を行なっています。 COM設定が不定な状態で使用することになり、設定できるようにしたのですがエラーが発生してしまいます。 [Unit1.cpp側] if (!CommOpen()){ Application->MessageBox("ポートを開けません","回線オープン",MB_ICONEXCLAMATION | MB_OK); return; } [Unit1.h側] int FChPort;  // シリアルポートナンバー HANDLE hCom; DCB comdcb; COMMTIMEOUTS comtout; BOOL CommOpen() { FChPort = 1; //シリアルポートのオープン char szComPort[10]; wsprintf(szComPort, "COM%d", FChPort); hCom = CreateFile( szComPort, GENERIC_READ | GENERIC_WRITE, 0, NULL,OPEN_EXISTING, 0, NULL ); if(hCom==INVALID_HANDLE_VALUE){ return FALSE; } return TRUE; } 上記が現状です。 RadioButton1~9にはCaptionが「COM1」~「COM9」になっているため CheckされているCaptionの、右から1文字をCOMポート設定に割り当てたいと考えています。 そこで、 FChPort = 1; の部分を FChPort = StrToInt(RightStr(Unit1->RadioButton1->Caption,1)); に変更したのですが、デバッガ例外が発生し、読み込み違反があったというエラーが発生してしまいました。 (例としてRadioButton1で試しました。) なぜなのでしょうか? また、このような場合、どのようにすればCOM設定ができるのか教えていただきたいのですが…。 よろしくお願いします。 開発環境はWindows XPです。

質問者が選んだベストアンサー

  • ベストアンサー
  • KoHal
  • ベストアンサー率60% (110/181)
回答No.2

>.cpp側で書けば値も取れ、動作できるのですが、 >.h側に書くと、フォーム上の内容が読めなくなります。 それは要はCommOpen()の定義内からフォームが見えてる(フォームのクラス定義と関数定義が同じスコープ内にある)かどうかですね。 CommOpen()をフォームのメンバにするのが一番手っ取り早い解決策です。※A //フォームのヘッダのprivate:以下に  bool CommOpen(); //フォーム(Form1とします)のソースファイル(.cpp)に  bool Form1::CommOpen() { ... } メンバにしないなら、そもそもCommOpen()の定義内でフォームメンバ(RadioButton1など)を直接参照することが(できないことはないんですが)、あまりきれいではないと思います。 それより、CommOpen()に引数としてポート名なりポート番号を渡すようにしたほうが良いように思います。もちろんケースバイケースなのですが。※B //bool CommOpen( int FChPort );とする //CommOpen()を呼び出すフォームのイベントハンドラで  CommOpen( RadioGroup1->ItemIndex +1 ); //ItemIndexは0始まり これならポートを開いたあとの処理を含め、実行関数群をフォームから独立したライブラリにすることも可能ですし。 とりあえず、※Aか※Bで問題なく動作するかテストしてみてください。 複数のフォームを使う場合は、フォーム間でポート番号のようなデータをどう受渡しするのかを検討する必要があります。 それはCommOpen()が成功してから改めて質問してください。

ev94-lo
質問者

お礼

※Aの方法を使ってみたところ無事解決しました! これで悩んでいた部分が解消されて一気に他の部分もできそうです。ありがとうございました! >フォーム間でポート番号のようなデータをどう受渡しするのかを検討する必要があります。 こちらの方は自分でもう少し考えて、それでもわからなかったら改めて質問させていただきます。 ありがとうございました。

その他の回答 (1)

  • KoHal
  • ベストアンサー率60% (110/181)
回答No.1

不明点がいくつかあります。補足してください。 >FChPort = StrToInt(RightStr(Unit1->RadioButton1->Caption,1)); ここでつかわれている"Unit1"はただしく定義されているのですか? つまり"Unit1"はRadioButton1を所有するフォームないしコンテナオブジェクトのポインタで間違いないのですか? そしてなぜ"Unit1->"が必要なのですか? ComOpen()はフォームとは別のユニットで定義されているのですか? COMポートを開く以前にTRadioButtonや文字列の扱いに問題があるような気がしますが、質問で提示されたコードだけからはどこが原因なのか判断が出来ません。 ただ、エンドユーザに開くポート番号を選ばせるならTRadioGroupをつかったほうが早いと思いますが。 それならTRadioGroup::ItemIndexで選択された番号が取得できます。 TRadioButtonをつかう必要があるなら、選択されたオブジェクトに対して //RadioButton1が選択されているとする hCom = CreateFile(  RadioButton1->Caption.c_str(),  GENERIC_READ | GENERIC_WRITE, 0, NULL,OPEN_EXISTING, 0, NULL ); これでいいような気がします。

ev94-lo
質問者

補足

回答ありがとうございます。 文字数の制限に気を取られて、説明不足になっていることに気づきませんでした。 >"Unit1"はRadioButton1を所有するフォームないし… →はい。当初は別フォームで行なおうと思っていましたが、できなかったために"Unit1"フォームへ移動してあります。 ただ、できれば別フォームに置きたいと思っています。 >なぜ"Unit1->"が必要なのですか? →"Unit1->"を入れないと、「未定義の関数RadioButton1を呼び出した」というエラーが出るために付けています。付けるとエラーは無くなりコンパイルできますが、動作時に読み込み違反があったというエラーがあったというエラーが発生します。 TRadioGroupに関してですが…忘れていました。TRadioGroupを使うように変更しました。 .cpp側で書けば値も取れ、動作できるのですが、 .h側に書くと、フォーム上の内容が読めなくなります。 おそらく、原因はここで、根本的に間違えてるだけな気がしますが、そこがどこかわからず非常に困っています…。 RadioButtonから修正前に教えていただいたプログラムにしましたが、やはり同様の現象が発生してしまいました。

関連するQ&A

  • CreateFileしてもうまくいきません・・。

    シリアルポートで通信するためのプログラミングを始めたばかりなのですが、COMポートのオープンが成功しません。 以下を実行しているのですが、何が間違いでしょうか? ちなみに、PCMCIAに挿入したPCカードから通信したいと考えています。単純に"COM1"というのであっているのかも分かりません・・。 よろしくお願いします。 void CMyDlg::OnReset() { HANDLE hCom; hCom = CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED NULL ); if(hCom == INVALID_HANDLE_VALUE){ MessageBox("ポートオープン失敗"); } else{ MessageBox("ポートオープン成功"); } }

  • シリアル通信について。

    PICからPCにデータ(電圧:最大値5)を受信させようとしています。 受信には C++を用いたプログラムを自作したいのですが、 どうしてもうまくいかなかったため投稿させていただきました。 症状としては、まずポートを開く事すら出来ていません。 RS232c {USBで変換) が接続されているポートはCOM1です。 ポートが開くか確かめるプログラムとしては、次のようなソースを使いました。 #include<windows.h> #include<iostream> using namespace std; int main(void){ HANDLE hCom; hCom = CreateFile( (LPCWSTR)"COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hCom == INVALID_HANDLE_VALUE) { cout<<"シリアルポートを開くことが出来ませんでした。\n"<<endl; return false; } CloseHandle( hCom ); return 0; } これを実行すると「シリアルポートを開くことが出来ませんでした。」としかなりません。 ( (LPCWSTR)"COM1"となっているのは、「'CreateFileW' : 1 番目の引数を 'const char [5]' から 'LPCWSTR' に変換できません。」  と出てしまったためです。) ハイパーターミナルを用いてCOM1からデータを受信できていることは確認しましたので、 通信が出来ていないわけではないようなのです。 ありふれた質問である事は重々承知の上ですが、 このソースでシリアルポートが開けない理由を教えていただければ幸いです。 環境:Visual C++ 2008 Express Edition Microsoft Windows XP Version 2002 Service Pack 3

  • COMポートの変更方法

    Libletto ffを使っています。YAMAHAのMIDI音源をつなげたいのですが、うまくいきません。 MIDI音源はシリアルで繋ぐのですが、ポートが無いため、 USB-シリアルの変換ポートを使用しています。 原因はまだ不明なのですが、音源のドライバがシリアルポートのCOM1を選択しているのに対し、USB-シリアル変換ポートがCOM3を割り当てているのが原因ではないかと思っています。(ドライバがCOM1以外を選択させてもらえません) そこで・・・。 COM3をCOM1に設定しなおすのはどうすればいいでしょうか?(COM1は赤外線ポートが割り当てられているので、使わないから無効にしようと思っています) ぜひ宜しくお願いいたします。

  • バイナリ送信で出るエラーコードの意味が分かりません

    シリアルポートでバイナリを非同期で送信するプログラムを作成しています。 以下のソースで実行すると、「重複したI/O処理を実行しています」というエラーがでました。 何が間違っているのか分りません・・。 どうかご指摘お願いします。 void CMyDlg::OnReset() { //COMポートオープン HANDLE hCom; hCom = CreateFile( "COM4", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ); //通信設定 DCB dcb; GetCommState(hCom,&dcb); dcb.BaudRate = 9600; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; SetCommState(hCom,&dcb); OVERLAPPED old; // オーバーラップ構造体の初期化 ZeroMemory( &old, sizeof(old) ); old.Offset = 0; old.OffsetHigh = 0; old.hEvent = NULL; //データ送信 char wbuf[7] = {0x02,0x00,0x01,0x00,0x31,0x15,0x12}; DWORD wbyte; WriteFile(hCom,wbuf,sizeof(wbuf),&wbyte,&old); //エラーコード取得&文字列に変換&表示 LPVOID lpMessageBuffer; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),//エラーコード取得 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMessageBuffer, 0, NULL ); MessageBox((LPCTSTR)lpMessageBuffer); //メッセージボックス LocalFree( lpMessageBuffer ); //COMポートクローズ CloseHandle(hCom); }

  • シリアル通信の受信待ちについて

    シリアル通信で10Byte受信するまで待ち続けたいのですが、0ByteでReadFileが抜けてしまいます。 ReadFileの最後のパラメタが、NULLならば第3パラメタの値まで待ち続けると思っていたのですが、なにか設定が足りないのでしょうか? タイムアウト値は0にしています。(色々変えて見ましたが同じでした) HANDLE hComm; /* シリアルポートのハンドル */ DCB dcb; char* pszBuf="1234567890"; /* 書込・読込領域 */ hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); GetCommState(hComm, &dcb); /* DCB を取得 */ dcb.BaudRate = 9600; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcb.ReadIntervalTimeout = 100; dcb.ReadTotalTimeoutMultiplier = 0; dcb.ReadTotalTimeoutConstant = 0; dcb.WriteTotalTimeoutMultiplier = 10; dcb.WriteTotalTimeoutConstant = 500; SetCommState(hComm, &dcb); /* DCB を設定 */ DWORD dwRead; /* ポートから読み出したバイト数 */ ReadFile(hComm, pszBuf, 10, &dwRead, NULL);

  • Win32でシリアル通信

    現在.NET2003のWin32を使ってシリアル通信を行うプログラムを作成中なんですが、CreateFile()、WriteFile()といった関数を使っているのですがどうもうまくいきません。 どなたかWin32について詳しい方、ご教授頂けないでしょうか?また、こういった事が書いているHP等をご存知の方教えて頂けないでしょうか? ちなみに、ポートを開く部分は下記のようになっているのですが、何か間違いがあれば教えて下さい。 お願い致します。 /* シリアルポートを開く */ BOOL SerialOpenPort(int nPortNumber) { char szSerial[256]; if(g_ahSerial[nPortNumber - 1] != NULL) { return FALSE; } sprintf(szSerial, "COM%d", nPortNumber); g_ahSerial[nPortNumber - 1] = CreateFile( szSerial, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );   if(g_ahSerial[nPortNumber - 1] == INVALID_HANDLE_VALUE) { g_ahSerial[nPortNumber - 1] = NULL; return FALSE; } if(!InitDCB(nPortNumber)) { return FALSE; }  if(!InitCommTimeOuts(nPortNumber)) { return FALSE; }  return TRUE; }

  • COM3を削除したい

    WindowsXPに、VMWarePlayerをいれUbuntuを走らせて、シリアル通信を行っいました。 その後、USBシリアルアダプタを入れたり、Bluetooth基盤を増設したりし、いつの間にか、シリアル通信が出来なくなってしまいました。 ポートのオープンは出来ているんですが、データは送られません。 Windows側でディバイスマネージャで見るとCOM1 COM9(Bluetooth)がありますが、プログラム上では、COM1、COM3、COM9、COM10が見つかります。 USBシリアルアダプタを差した場合は、COM4がディバイスマンージャに現れるので、削除しました。 VMPlayerではCOM1 COM3があると通信できない、と言う記事を見かけたので COM3を削除したいのですが、ディバイスマネージャ上にない場合、どのようにすればよいでしょうか?

  • CreateFile関数でCOMポートが開けない

    以下の手順でCOMポートをオープンすると、(4)のCOMオープンが必ず失敗します。 GetLastError関数でエラーコードを取得するとERROR_FILE_NOT_FOUNDが返ってきました。 心優しい方、(4)のCOMオープンを成功させる方法を教えていただけないでしょうか? (1)CreateFile関数でCOMポートをオープンし、オープン中にUSBを抜き差しする。 (2)PurgeComm関数で送受信バッファをクリア (3)CloseHandle関数でCOMポートのハンドルをクローズ (4)CreateFile関数でCOMポートを再度オープン←NG 以上、どうぞよろしくお願いいたします。

  • シリアルポートをCOM5からCOM1へ戻したい。

    シリアルポートは通常COM1だと思うのでが、私のPCはデバイスマネージャーで確認するとCOM5となってます。COM1に戻したいのですが、戻し方わかりませんので、どなたか教えて下さい。よろしくお願いします。  実は、所有のデジカメがシリアル接続でして、デジカメが認識できない状態です。接続ソフトはCAMEDIA MASTER2.5で、ポートの設定が1~4までしかないのです。それでなにがあってもCOM1(2でも3でも4でも可)に変更したいンです。おねがしまーす。  PS.バイオスの設定を結構いじりました。PCは日立のプリウスデッキです。

  • COM1ポート開き,9600,8,なし,1,HWの設定で垂れ流しデータ読むだけのCプログラム作って

    ください。Borland C v5.5 無料版 on windows2000 on thinkpadのDOS窓で動いて欲しいだけ、です。基本が解れば、あとは自分で改造したいですので、どなたか、お優しい方、何卒お願いします! 本もないのに、無謀ですが、たとえば以下のは参考になりますか?以下のはC++ですので、ちょっと私には解りません。C++でなく、Cで、書き下して欲しいです。 #include <windows.h> #include <iostream> #include <stdio.h> using namespace std; int main() { HANDLE hComm; char buff[190]; DWORD size; hComm = CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ); if( hComm == INVALID_HANDLE_VALUE ) exit( 1 ); ReadFile(hComm, buff, 200, &size, NULL); cout << buff << endl; getchar(); CloseHandle(hComm); return 0; }

専門家に質問してみよう