ady.at.infoseek.co.jp







開発環境





VC++6(エンタープライズ以上のバージョンまたはVisualStudio)、
WindowsCE toolkit for VC++の順にインストールすればよい。
eMbedded Visual Tools 3.0では、HPC2.0用のプログラミングはできない。

WinCEエミュレータは、NT対応なので、わざわざNT4を買ったが、
動作がおかしいので今は使用していない。




日本語コードに戸惑う





WindowsCEシステム内では日本語は全部unicodeで統一されている。
しかし、システム外へデータを出すときは、シフトJISやJISにしなくてはならない。

あまりに基本的過ぎるのかこのへんの解説がどの参考書にも皆無であり、
さらにMSDNのヘルプは「unicode」=「ワイド文字」「シフトJIS」=「マルチバイト文字」と表記されており、我々初心者は必ず混乱する。

WindowsCEプログラミングで、ワイド文字、マルチバイト文字の理解は必須であり、
以下の説明は、とにかく目立つようにしてほしい。
ワイド文字、マルチバイト文字とはANSI Cで決まっているデータ構造の違いをあらわす言葉である。 ”ワイド文字”=「1文字表現するのに2バイト用いる文字」 unicodeは2バイトでひとつの文字を表す。という構造である。という意味。 (ちなみに、データ圧縮のための可変長unicodeという亜種が存在するので、 WindowsCEであつかうunicodeをワイド文字と表現したmicrosoftに罪はない。) ”マルチバイト文字”=「1バイト以上で文字を表現するデータ構造の文字」 JISやシフトJISは、漢字(全角)は2バイトを使って表し、 半角文字(カタカナや英数字)は1バイトで表す。 ひとつの文字をあらわすデータの長さが複数混在している構造。
したがって、構造そのものが違うunicodeとシフトJISは、
それを格納する変数の型も違うのである。




ファイル操作のコーディング





// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
HANDLE hFile;

hFile = CreateFile(
 TEXT("\\Temp\\test.txt"),//ファイル名
 GENERIC_WRITE,		//アクセスモードは書き込み。
 0,			//オブジェクトの共有方法。0なら共有なし。
 NULL,			//取得したハンドルを子に継承するか?NULLはしない。
 CREATE_ALWAYS,		//作成方法はいつも書き潰し。
 FILE_ATTRIBUTE_NORMAL,	//ファイル属性は特になし。
 NULL);			//テンプレート。よくわからない。

if( hFile != INVALID_HANDLE_VALUE )
{
 WCHAR buf1[80];//TCHARは互換性確保のマクロ。
 char buf2[80];	//ファイルから読み込んだ無加工のデータが入る。
 DWORD wsize;	//書き込んだバイト数が入る。

 memset( buf1, '\0', sizeof( buf1));
 memset( buf2, '\0', sizeof( buf2));

 swprintf( buf1, TEXT("%s\r\n"), TEXT("1230123ABCaaa"));

 //これよりシフトjisに変換

 WideCharToMultiByte(//Unicodeをマルチバイト文字(シフトjis)へ。
  CP_ACP,	//コードページはANSI。他にMacintoshやUTF-7/8などが選べる。
  0,		//処理速度とマッピング方法。通常は0(速い)。
  buf1,		//ワイド文字列(Unicodeが入っている)のポインタ。
  -1,		//文字数。-1のときはNULLまで自動計算。
  (LPSTR)buf2,	//新しい文字列バッファ。
  sizeof( buf2),//バッファサイズ。
  NULL,		//変換できなかったことを示す文字(例。■など)の指定。
  NULL		//↑を指定したことを示すフラグ。両方NULLだと速度がアップ。
 );

 //書き込み。
 WriteFile( hFile, (LPVOID)buf2, strlen( buf2), &wsize, NULL);


 //もいっぺん書き込み。
 swprintf( buf1, TEXT("%s\r\n"), TEXT("これでやっと文字が出せます"));
 WideCharToMultiByte( CP_ACP, 0, buf1, -1, (LPSTR)buf2, sizeof( buf2), NULL, NULL);
 WriteFile( hFile, (LPVOID)buf2, strlen( buf2), &wsize, NULL);

 CloseHandle( hFile);
}

ファイルを読み込む場合。 

// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
//コモンファイルダイアログ出します。
CFileDialog dlgfile( TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_READONLY, TEXT("*.*"), NULL);

//モーダルなので入力を待ってから次の処理へ。
if( dlgfile.DoModal() == IDOK )
{
 WCHAR fname[_MAX_PATH];

 //ファイル名を得る。
 swprintf( fname, TEXT("%s"), dlgfile.GetPathName());

 HANDLE hFile;

 //ファイルのオープン。
 hFile = CreateFile(fname,GENERIC_READ, FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
 if( hFile != INVALID_HANDLE_VALUE )
 {
  int size;
  char *buf1;
  WCHAR buf2[255];
  DWORD rsize;

  size = GetFileSize( hFile, NULL);
  buf1 = (char*)malloc(size + 1);//一気読み込み。(短いファイルを想定)
  ReadFile( hFile, buf1, size, &rsize, NULL);
  buf1[size] = TEXT('\0');
  MultiByteToWideChar( 
   CP_ACP,	//コードページ(書き出しと同じ)はANSI。
   0,		//制御文字やらの種類を指定…しない。
   buf1,	//変換する文字列へのポインタ。
   -1,		//文字列はNULLで終わっていることを表す。
   buf2,	//受け取るバッファ。
   sizeof( buf2)//そのサイズ。
   );

 AfxMessageBox( buf2, NULL, MB_OK);

 free( buf1);
 CloseHandle( hFile);
}
<補足>
どうやらunicode<->シフトJIS変換は
wcstombs( s, w, sizeof(s));
mbstowcs( w, s, sizeof(w));
を使ったほうが簡単のようです。