2007年9月25日火曜日

文字列ポインタ

文字列ポインタについてまとめました。

いろいろありますが、●を使用しておけば無難だと思います。

 LPSTR char型ポインタ。
 LPCSTR    const char型ポインタ
 LPWSTR    wchar型ポインタ
 LPCWSTR    const wchar型ポインタ
●LPTSTR    TCHAR型ポインタ LPSTR/LPWSTRに置換えられる
●LPCTSTR const TCHAR型ポインタ LPCSTR/LPCWSTRに置換えられる

2007年9月21日金曜日

C++2005 テキストボックス char型文字 変換方法

テキストボックスから、文字を取得するには、sprintf() が一番簡単です。

■テキストボックスからchar型に変換して文字を取得する)
--------------------------------------
#include <stdio.h>

char buf[256];
sprintf_s( (char*)buf , sizeof(abuf) , "%s" , textBox1->Text::get() );
--------------------------------------
テキストボックスの文字数が、bufより多いとエラーが発生しますので、
textBox1->TextLength::get() で対策するのがいいでしょう。

(余談)以下のような方法もありますが、
[共通言語ランタイム サポート、古い構文 (/clr:oldSyntax)]
に設定変更する必要があるため個人的にはおすすめできません。
1)Marshal::StringToHGlobalAnsi(str)
2)PtrToStringChars(str)

2007年9月20日木曜日

C++2005 char型文字 テキストボックス 表示方法

ずっとずっと悩んでましたが、やっと解決しました。

次のソースは、char型の文字「$」を System::String型に変換してテキストボックスに入力します。

■解決したソース(テキストボックスへchar型文字を入力する)
--------------------------------------
char buf[2] = "$";
textBox1->Text += System::Runtime::InteropServices::Marshal::PtrToStringAnsi((IntPtr)buf);
--------------------------------------

これで、CreateFile()を使用したシリアルポート受信がテキストボックスで確認できます!

2007年9月11日火曜日

VC++2005 で CreateFile 問題解決

VC++2005 で シリアルポートがやっと使えるようになりました。

VC++6.0 で動いていたソースですが、 VC++2005 上でコンパイルすると、CreateFile でエラーが発生します。

[ソース]
Shandle = CreateFile( "COM1" , GENERIC_READ | GENERIC_WRITE , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );

[エラー]
error C2664: 'CreateFileW' : 1 番目の引数を 'char [256]' から 'LPCWSTR' に変換できません。

そこで、エラーがでないようにキャストするとエラーは無くなります。

[ソース]
Shandle = CreateFile( (LPCWSTR)"COM1" , GENERIC_READ | GENERIC_WRITE , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );

しかし、ハンドルが取得できませんでした。

■解決方法
VC++2005 で CreateFile と記述すると、CreateFileW になってしまうため、"COM1"などのシリアルポートのハンドルが取得できなくなると思います。
そこで、 CreateFileA を使用します。

[ソース]
Shandle = CreateFile( "COM1" , GENERIC_READ | GENERIC_WRITE , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );

これで、ハンドルが正常に取得できるようになりました。

2007年9月8日土曜日

error LNK2019: がやっと解決しました!

以下のエラーが解決せずに、二週間も悩んでいましたが、今日やっと解決しました。

----------------------------------------
error LNK2019: 未解決の外部シンボル __imp__DispatchMessageA@4 が関数 _WinMain@16 で参照されました。
----------------------------------------

Win32 テンプレートが使えなかったのが原因のようです。


■解決方法:以下の手順4と5を実施するとOKです。
http://www.microsoft.com/japan/msdn/vstudio/express/visualc/usingpsdk/

2007年9月1日土曜日

.NET SerialPort の IsOpen() の戻り値がおかしいときがある

.NET SerialPort の IsOpen()メソッドですが、
シリアルポートがすでにオープンしているかどうかを
調べるために使用すると思うのですが、
ちゃんと検出してくれないときがあります。

例えば、COM1 を別のアプリケーションで使用(オープン)しているときに、
IsOpen()を使用すると、false(クロース状態)で返します。


-- 別のアプリケーションで COM1オープン中 --
if( serialPort1->IsOpen::get() == false ){ // ここでは false が返る
serialPort1->Open();
}


よって、続けて Open()メソッドを実行すると以下のエラーが出ます。

----------------------------------------------------------------
'System.UnauthorizedAccessException' のハンドルされていない例外が System.dll で発生しました。
追加情報: ポート 'COM1' へのアクセスが拒否されました。
----------------------------------------------------------------


ところが、COM1がクローズされている状態で Open()メソッドを実行し、
IsOpen()で状態を見ると、ちゃんと true(オープン状態)で返してくれます。


-- COM1クローズ中 --
serialPort1->Open();
if( serialPort1->IsOpen::get() == false ){ // ここでは true が返る
serialPort1->Open();
}


解決方法がわからないので、.NET SerialPort 今は使用しないことにします。
シリアル通信は、CreateFile() を使用しようと思います。