いまさらの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が必要である。日本語のPocketPCのwince.nlsは当然問題ないが、英語版や中国語版のPocketPCのwince.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)ワード境界しかアクセスできない
(7)HELPが独特
- WindowsCE Helpという独特の記法のHTMLで書かないといけない。
(8)WindowsとWindowsCE,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
(11)インストーラはCABファイルを作成する。
- 構成ファイルやCPUタイプを定義した.inf ファイルを作り、CabWizでCABを作成する。CabWizはeMbedded Visual Toolsに付属する。