hishidaの開発blog

EBシリーズ(EBPocket,EBWin,EBMac,EBStudio),KWIC Finder,xdoc2txt,読書尚友の開発者ブログ

いまさらのWindowsCEプログラミング(4) - WindowsからWindowsCEへの移植の注意点

今回は Visual C++ のプログラムを eMbedded Visual C++に移行する上での注意点を述べます。

(1)プロジェクトの拡張子が異なる
  プロジェクトファイル ワークスペース
Visual Studio 6.0 .dsp .dsw
eMbedded Visual Tools .vcp .vcw

eMbedded Visual Tools上でプロジェクトを新たに作る必要がある。なお、eMbedded Visual Tools3.0と4.0では、プロジェクトファイルの拡張子は同じなのに内容が違い、互換性がない。3.0のプロジェクトを4.0で読み込むと変換されるが、3.0で使用できなくなる。

(2)UNICODE対応が必要

WindowsCEは内部コードがUNICODEなので、UNICODEアプリケーションとして開発する必要がある。

  • 文字列は全て_T()で囲む。
  • charはTCHARで宣言する。
  • 文字列操作ではUNICODE用の関数を用いる。汎用テキスト ルーチンを使用すると、マクロによってUNICODEとMBCSでソースを共有できる。
	TCHAR szFileName[_MAX_PATH];
	_tcscpy( szFileName, _T("profile.ini") );

例:strcpy()の汎用テキストルーチンとして_tcscpy()が定義されており、_MBCSが定義されていると_mbscpy()に、_UNICODEが定義されているとwcscpy()に、どちらも定義されていないとstrcpy()に展開される。

なお、TCHARは内部で2バイトなので注意。例えば次の例でbufは512バイトなので、(a)は間違い、(b)とする

	TCHAR buf[256];
	memset( buf,0,256) ;			←(a) ×
	memset( buf,0,sizeof(TCHAR)*256);	←(b) ○


MBCSとUNICODE文字コードを変換する必要がある場合は、MultiByteToWideChar() と WideCharToMultiByte()が使用できる。ただしコードページ932(ShiftJIS)を持ったwince.nlsが必要である。日本語のPocketPCwince.nlsは当然問題ないが、英語版や中国語版のPocketPCwince.nlsだと、日本語フォントがあっても文字化けしてしまう。これがいわゆるヌルズ(nls)問題の正体。

(3)C言語の標準関数が少ない
  • fopen() や fgets() といったUNIXのf*系のfile I/O関数がないので、Win32APIで置き換える必要がある。(ただしCE3.0以降はfopen()がある。EBPocketは当初f*系を使用していたが、PocketPostPetで動かないので、結局Win32APIで書き直した)
  • str*の文字列操作系の関数が少ない。自分で関数を追加する必要あり。
  • qsort()はあるのにbsearch()がない。
(4)CEのWin32APIはWindowsのサブセットであり、一部の機能がサポートされない

詳細はMSDNを見ていただくとして、EBPocketの開発で特に困った点は:

  • TextOut()がないので、ExtTextOut()で代用
  • GlobalAlloc()がないので、LocalAlloc()で代用
  • ファイルからbitmapをロードするのにLoadImage()が使用できないので、SHLoadDIBitmap()で代用
  • OpenMutex()がない。CreateMutex()で代用
  • CreateFont()がないので、CreateFontIndirect()で代用
(5)MFC for Windows CE は、Win32 MFC のサブセットなので、一部の機能はサポートされない

重要な違いは、

  • マルチ ドキュメント インターフェイス(MDI) をサポートしていない。SDIとダイアログベースのみ。
  • CRichEditがない。
  • 同じクラスが存在しても、一部の機能がサポートされないものがある。例えばCListBoxにオーナードローがない。
  • MFC for Windows CE では、コマンド バーと呼ばれる特有のクラス(CCeCommandBar)をサポートしている。コマンド バーは、メニュー バーとツール バーの機能を兼ね備えたコントロールであり、画面のスペースを節約できる。
(6)ワード境界しかアクセスできない
  • WindowsCEのCPUはRISCアーキテクチャなので、ワード境界しかアクセスできない(奇数アドレスにアクセスできない)。Windows用のサンプルプログラムから不用意にコードを流用すると、x86上のエミュレータでは動くのに実機ではアクセス・バイオレーションになることがある。
(7)HELPが独特
  • WindowsCE Helpという独特の記法のHTMLで書かないといけない。
(8)WindowsWindowsCE,PocketPCでソースを共通化する場合、定義済みマクロで切り分ける

_WIN32_WCEにはWindowsCEのバージョン数値が入る。また_WIN32_WCE_PSPCはPocketPCのみ定義されているので、H/PCとPPCでコードを分けることができる。

例1:WindowsCEのみのコード
#if defined(_WIN32_WCE)
...
#endif
例2:PocketPCのみのコード
#if defined(_WIN32_WCE_PSPC) && (_WIN32_WCE >= 212)
...
#endif
(9)相対パスは使えないので絶対パスで指定する
(10)ClearTypeが使える(WindowsCE.NET4.x以降)
  • LOGFONT構造体のlfQualityに 5 を設定すると、ClearTypeが使える。
(11)インストーラはCABファイルを作成する。
  • 構成ファイルやCPUタイプを定義した.inf ファイルを作り、CabWizでCABを作成する。CabWizはeMbedded Visual Toolsに付属する。