Delphi 2006 で行う PocketPC アプリケーション開発

By: Tsutomu Inoue

Abstract: この記事は、Delphi .NET Compact Framework Compiler と Pocket PC アプリケーションを開発するための Delphi 2006 プラグインについての情報を提供します。

    はじめに

Delphi 2005 のリリース数ヵ月後、ボーランドは Delphi .NET Compact Framework コンパイラのプレビュー版を作成しました。現行の Delphi 2006 には、Compact Framework のコンパイラの完全版が含まれています。今のところ、Compact Framework デザイナはありませんが、いくつかの拡張ツールを使うことによって、数種類の Pocket PC や スマートフォンと、Windows CE オペレーティングシステムが動作するすべてのデバイス上で実行できるファイルを、非常に簡単に作成できます。
この記事では、NET Framework のデスクトップ版とコンパクト版の違いを説明すると共に、Delphi 2006 を使って Pocket PC アプリケーションを開発及びテストする方法を、ステップバイステップで紹介します。

    .NET Compact Framework

Pocket PC デバイスと Windows CE が動作するその他のデバイスは、現在 .NET Compact Framework(以降 .NET CF) をサポートしています。.NET CF は、通常の .NET Framework の多くの部分を含んだサブセットで、通常の .NET Framework と同様に多くの利益をもたらします。
また .NET CF は、モバイルデバイスに特化した開発を行うための、いくつかのライブラリも提供します。

しかし、フル機能の .NET Framework において有効なすべてのクラス、プロパティ、メソッドが、Compact Framework 上に実装されているわけではありません。今回の記事によって、それらの最も重要な違いと、一連の作業について紹介をします。

Delphi 2006(と 2005)は、現行のすべての Pocket PC で動作すると思われる、.NET CF 1.0 をサポートします。Microsoft は、最近 (DateTimePicker、MonthCalendar、LinkLabel のような)新しいコントロール、電話制御のためのいくつかの新しいマネージド API 、メッセージング、構成ファイルのサポート等を含んだ、.NET CF のバージョン 2.0 をリリースしています。

    Windows Mobile エミュレータ

モバイルアプリケーションをテストするために、あなたが使用する PC にエミュレータをインストールする必要があります。
Microsoft のWebサイトには、ダウンロード可能な2種類のエミュレータがあり、それらのエミュレータイメージはモバイルオペレーティングシステムのためのものです。Windows Mobile 2003 と 2003 Second Edition オペレーティングシステムは、現行の Pocket PC で最も多く使われています。最新の Pocket PC には、Windows Mobile 5.0 がインストールされていることでしょう。

    Windows CE 5.0 エミュレータ

最も古い Windows CE 5.0 エミュレータ(Emulator_500.exe)は、x86 CPU を搭載する Pocket PC と Smartphone 2003 オペレーティングシステムの為のものです。このエミュレータで動作する x86 用 Windows Mobide 5.0 のイメージは存在しません。

    Windows Device エミュレータ 1.0

Microsoft Visual Studio 2005 がインストールされている場合、新しいエミュレータが「デバイスエミュレータ」(と デバイス エミュレータ マネージャ)と呼ばれることに気づかされるでしょう。
最近になって、Microsoft は、スタンドアロンバージョンのデバイスエミュレータをリリースしました。この新しいデバイスエミュレータは、以前のものより(容易なインストール、追加の機能、Active Sync のサポート、VMWare セッションでの実行、改良されたヘルプファイル、のような)顕著な改善が見られます。しかし、この新しいエミュレータは、ARM プロセッサのためにコンパイルされたコードしか実行できません。そのため、古い x86 OS イメージで実行しようとしても、 "Invalid or missing ROM image"(ROM イメージが無効または存在しません)というエラーメッセージが目にすることになるしょう。

もし、あなたの使用する PC に 仮想マシンネットワークドライバがないとき、先にそれをダウンロードしてインストールします :

ローカライズされたエミュレータイメージと拡張ツールも利用可能です :

もうしばらくすると、ARM CPU 用の Windows Mobile 2003 SE が Microsoft Webサイトでダウンロード可能となります。

もっと新しいベータ版もこちらにあります。ただし、まだいくつかバグがあります :

    パスと起動時のパラメータ

Hide image
Windows Mobile Emulators

Windows CE 5.0 エミュレータと PPC 2003 SE イメージ (x86) のパス

エミュレータ C:\Program Files\Windows CE 5.0 Emulator\Emulator_500.exe
イメージ (2003 SE) C:\Program Files\Pocket PC 2003 Second Edition Emulators\WWE\
イメージ (2003) SDK から C:\Program Files\Windows CE Tools\wce420\POCKET PC 2003\Emulation
スキン C:\Program Files\Pocket PC 2003 Second Edition Emulators\WWE\


デバイスエミュレータ 1.0 (スタンドアロン版) と PPC 5.0 イメージ (ARM)

エミュレータ C:\Program Files\Microsoft Device Emulator\DeviceEmulator.exe
イメージ (5.0 MSFP) C:\Program Files\Microsoft Windows Mobile 5.0 MSFP Emulator Images\
イメージ (5.0) from SDK C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0 Pocket PC SDK\Deviceemulation\0409
ローカライズされたイメージ (5.0) C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0 Emulator Images for Pocket PC - NLD\Deviceemulation\0413
スキン C:\Program Files\Microsoft Windows Mobile 5.0 MSFP Emulator Images\


デバイスエミュレータ 1.0 (VS2005) と PPC 20003 (ARM) パスと、PPC 5.0 イメージ (ARM)

エミュレータ C:\Program Files\Microsoft Device Emulator\1.0\DeviceEmulator.exe
イメージ (2003 SE と 5.0) C:\Program Files\Microsoft Visual Studio 8\SmartDevices\Emulators\Images\
スキン C:\Program Files\Microsoft Visual Studio 8\SmartDevices\Skins\


起動時のパラメータ

  エミュレータ イメージ ファイル (Pocket PC または スマートフォン) へのリンク
/sharedfolder 開発したアプリケーションを入れる共有フォルダ. そうする事により、Pocket PC 上でこのフォルダをストレージカードリンクアクセス可能になる.
/video 解像度 (幅 x 高) と 色数。Pocket PC の場合は 240x320x16、スマートフォンの場合は 176x220x16
/ethernet エミュレータ内でのネットワークサポートのレベルの指定 (なし、共有、仮想的な切り替え)
/skin XML スキンファイルへのリンク。スキンは Windows CE のウィンドウ周りに表示される Pocket PC や スマートフォンのビットマップです。
このパラメータは必須ではありません。


エミュレータを開始するための VB スクリプト

Dim WshShell
Set WshShell = CreateObject("WScript.Shell")

q = Chr(34)
strCommandLine = q & "C:\Program Files\Windows CE 5.0 Emulator\Emulator_500.exe" & q
& " " & q & "C:\Program Files\Pocket PC 2003 Second Edition Emulators\WWE\Pocket_PC\PPC_2003_SE_WWE.bin" & q
& " /sharedfolder " & q & "C:\Program Files\NET CF\Shared" & q
& " /video 240x320x16" & " /ethernet shared"& " /skin "
& q & "C:\Program Files\Pocket PC 2003 Second Edition Emulators\WWE\Pocket_PC\PPC_2003_SE.xml" & q

WshShell.Exec(strCommandLine)
Dim WshShell
Set WshShell = CreateObject("WScript.Shell")

q = Chr(34)
strCommandLine = q & "C:\Program Files\Microsoft Device Emulator\DeviceEmulator.exe" & q
& " " & q & "C:\Program Files\Microsoft Windows Mobile 5.0 MSFP Emulator Images\pocketpc.nb0" & q
& " /sharedfolder " & q & "C:\Program Files\NET CF\Shared" & q
& " /video 240x320x16" & " /ethernet shared"& " /skin "
& q & "C:\Program Files\Microsoft Windows Mobile 5.0 MSFP Emulator Images\Pocket_PC.xml" & q

WshShell.Exec(strCommandLine)

これは1行のソースなので、コマンドライン規則によって途中の改行は削除します !

    .NET CF アセンブリ

開発したアプリケーションPocket PC にを配布する場合には、NET Compact Framework 1.0 の最新のサービスパックがインストールされていることを必ず確認してください。最新のサービスパックに含まれているアセンブリは、エミュレータイメージの中には既に含まれていますが、開発者が持っている 実機の Pocket PC に対しても、最新の .NET アセンブリをインストールする必要があるからです。Microsoft の Webサイトには Service Pack 3 があるはずです。このアセンブリのエンドユーザーバージョン(再配布パッケージ)は、自動的なインストーラによって導入されますが、それには ActiveSync が有効な状態で、Pocket PC が開発用の PC に接続されている必要があります。

    Delphi Pocket PC アプリケーションの作成、コンパイル、配布

最初の Delphi Pocket PC アプリケーションの作成を始めましょう。さしあたって、余計なプラグインは利用しないことにしましょう。

    Button を含むフォームのデザイン

1) はじめに、[ファイル | 新規作成 | Windows フォームアプリケーション - Delphi for .NET ] を実行します

2) フォームの大きさを設定します: Size.Width=240、Size.Hieght=320

3) フォームの Text プロパティを設定します : "Pocket PC"

4) Button を追加して、Text を変更します : "Delphi"

    .NET CF コンパイラを使ったプロジェクトのコンパイル

実行 (F9) ツールボタンを押すと、アプリケーションは .NET コンパイラによってコンパイルされます。しかし、私たちは Pocket PC 用の .NET Compact Framwork アプリケーションを作成しようとしています。そのため、普通のやり方で作業を続けることはできません。

このアプリケーションをコンパイルするには、Borland\BDS\4.0\Bin フォルダから起動できる Delphi .NET CF コンパイラ (DCCIL) を使わなければなりません。.dcpil と .dcuil の拡張子を持つファイルは、 C:\Program Files\Borland\BDS\4.0\lib\cf フォルダで見ることができでしょう。.dcpil ファイルが存在する場合は、これらに対応する .NET CF アセンブリ (DLL ファイル) を開発用の PC にインストールする必要はありません。この DCCIL コンパイラは、Delphi 2006 IDE からは直接的に起動されることはありません。

DCCIL コンパイラを起動するための2種類の方法 :

面倒な方法は、コンパイラを実行するための短いスクリプトを作成することです。私は、コンパイルを実行するために、Delphi 2005 の VBScript を変更しました。ツールプロパティダイアログ (ツールの設定) で、メニューに対してこのスクリプトアイテムを追加できます。タイトル (新しいメニューアイテムの表題のことです) 、プログラムの場所、マクロを含むパラメーリストを指定してください。

タイトル Compile with Delphi .NET CF compiler
プログラム C:\WINDOWS\system32\wscript.exe
パラメータ $SAVEALL "C:\Program Files\NET CF\Scripts\CompileCFNET.vbs" $NAMEONLY($PROJECT) $PROJECT


CompileNETCF.vbs

' CompileNETCF.VBS
' Compile project with Delphi 2006 .NET Compact Framework Compiler (DCCIL)
' February 2006 - Stefan Cruysberghs
' Delphi tools properties
' * Program : C:\WINDOWS\system32\wscript.exe
' * Parameters : $SAVEALL "path\CompileNETCF.vbs" $NAMEONLY($PROJECT) $PATH($PROJECT)
Dim WshShell, Fso, Args, Exec, i
Set WshShell = CreateObject("WScript.Shell")
Set Fso = CreateObject("Scripting.FileSystemObject")
Set Args = WScript.Arguments

If Args.Count = 0 Then MsgBox "No Delphi project given", 16, "Error" Else strProjectName = Args(0) strProjectFolder = "" For i = 1 To Args.Count-1
strProjectFolder = strProjectFolder & " " & Args(i)
Next strProjectName = Trim(Fso.GetBaseName(strProjectName)) strProjectFolder = Trim(Fso.GetParentFolderName(strProjectFolder)) strProject = strProjectFolder & "\" & strProjectName & ".dpr" If Not Fso.FileExists(q & strProject & q) Then MsgBox strProject & " does not exist", 16, "Error" Else q = Chr(34) 'quote ' Set paths strDCCIL = "C:\Program Files\Borland\BDS\4.0\Bin\dccil.exe" strCFUnits = "C:\Program Files\Borland\BDS\4.0\lib\cf" strLogFileName = strProjectFolder & "\CompileCFNETLog.pas" ' Extra compiler options. If .NET CF assemblies are not available/needed, set it to "" strCompilerOptions = "" 'strCompilerOptions = " -lu" & q & "C:\NETCFAssemblies\Microsoft.WindowsCE.Forms.dll"
' & q & " -lu" & q & "C:\NETCFAssemblies\System.Windows.Forms.DataGrid.dll" & q
' Delete all .dcuil files On Error Resume Next Fso.DeleteFile strProjectFolder & "\*.dc?il", True strCommandLine = "cmd /c > " & q & strLogFileName & q & " " & q & strDCCIL & q & " " & q & strProject & q & " -u" & q & strCFUnits & q & " -luSystem.Windows.Forms -luSystem.Data " & strCompilerOptions ' Compile the project with the DCCIL.exe Set Exec = WshShell.Exec(strCommandLine)

' Wait for application to exit Do While Exec.Status = 0
WScript.Sleep 1
Loop ' Show the log file (when extention of log is PAS, it will be opened in Delphi) WshShell.Run(q & strLogFileName & q) End If End If

これは1行のソースなので、コマンドライン規則によって途中の改行は削除します ! 

Marco Cantu から教えてもらったすばらしい方法では、 ライブラリパス を変更します。 [ツール | オプション | Delphi オプション | ライブラリ - NET ] で、 $(BDS)\lib\ パスを $(BDS)\lib\cf に( [置換] ボタンを使って) 変更します。これにより開発者は、 実行コンパイルビルド のアクションを実行できるようになります。また、それに加えて、 Code Insight も機能するようになります。そして、コンパイルせずに WinForm デザイナのメッセージログ (Error Insight)によって表示されるエラーを見ることもでき、Code Completion (コード補完) も快調に動作します。

次のスクリーンショットは、ライブラリパスを \Lib\CF に変更したことによる、.NET Framework と .NET Compact Framework の MessagBox (訳者注 原文では MessaageDlg となっていました) クラスのメソッドの違いを表しています。

Hide image
Click to see full-sized image

    コンパイルエラーの解決

ライブラリパスを変更してアプリケーションを実行 (またはスクリプトを実行) します。見ての通り、大量の 「未定義の識別子」 エラーによってコンパイルは失敗します。前に説明したように、完全版の .NET Framework で使用可能なクラス、メソッド、プロパティが、Compact Framework 上で必ずしもすべて実装されているわけではありません。

Borland Delphi for .NET コンパイラバージョン 18.0
Copyright (c) 1983,2005 Borland Software Corporation
.NET Framework v1.1.4322 が読み込まれました


Project1.dpr(8) 警告: W1026 ファイルが見つからない: 'WinForm.TWinForm.resources'

WinForm.pas(50) エラー: E2003 未定義の識別子 : 'SuspendLayout'
WinForm.pas(55) エラー: E2003 未定義の識別子 : 'Name'
WinForm.pas(56) エラー: E2003 未定義の識別子 : 'TabIndex'
WinForm.pas(62) エラー: E2003 未定義の識別子 : 'AutoScaleBaseSize'
WinForm.pas(65) エラー: E2003 未定義の識別子 : 'Name'
WinForm.pas(67) エラー: E2003 未定義の識別子 : 'ResumeLayout'

Project1.dpr(15) 致命的エラー: F2063 'WinForm.pas' ユニットはコンパイルできませ
んでした

クラスが未定義の場合、フォーム (またはソースコードの中) からそのクラスを削除しなければなりません。

TabIndex は .NET CF に存在しないプロパティの一つです。したがって、コンパイラは、未定義の識別子 "TabIndex" エラーを返してしまいます。フォーム (Windows フォームデザイナによって生成されたコード) の InitializeComponent メソッドから削除またはコメントアウトすべき他のプロパティとメソッドは次の通りです :

  • Name
  • TabIndex
  • TabStop
  • Index
  • AutoScaleBaseSize
  • ResumeLayout
  • SuspendLayout
  • AddRange

Hide image
InitializeComponent

プロジェクトファイル中の、[STAThread] 属性を削除しなければなりません。

"ファイル 'WinForm.TWinForm.resources' が見つかりません" の警告を解決するために、WinForm.resx ファイルをプロジェクトから削除する必要があります。これは、プロジェクトファイル中にあるリソースファイルへの参照を削除することで解決できます。[プロジェクト|プロジェクトから削除] メニューアイテムを選択し、リストから WinForm.resx アイテムクリックし [OK] ボタンをクリックすることによっても削除できます。

{$R 'WinForm.TWinForm.resources' 'WinForm.resx'}

すべてのエラーを解決した後、例の VBScript 起動することによりプロジェクトを再びコンパイルします。

     エミュレータでアプリケーションをテストする

さてこれで、共有フォルダに EXE をコピー出来ます。エミュレータをスタートさせ、同じ共有フォルダがセットされているかを確認します。エクスプローラを実行し、ストレージカード (=共有フォルダ) に移動して実行形式ファイルをスタートさせます。はじめての Delphi Pocket PC アプリケーションが実行されていますよ !

Hide image
Click to see full-sized image

.NET CF が開発者のモバイルデバイスにインストールされていれば、開発者は ActiveSync を使って、EXE を Pocket PC にコピーすることもできます。

    Delphi プラグイン

もちろん Delphi .NET CF コンパイラが快調に動作していますが、生成されたコードに対して多くの変更をデザイナの支援なしに手作業で行っていことに気づいているでしょう。幸いに、何人かの Delphi 開発者が、Delphi プラグインの作成という素晴らしい仕事をしてくれています。

    Compact Framework プロジェクトプリプロセッサ

Chee Wee Chua は、Compact Framework プロジェクトプリプロセッサ (MakeCFCompatible) を Borland CodeCentral に寄贈しました。この小さなプログラムは、E2003 エラーを発生されるすべての行を自動的にコメントに変更してしまいます。

    Compact Framework ビルドヘルパー

そして、Jeremy NorthCompact Framwork ビルドヘルパー (CFMH) と呼ばれるすばらしいプラグインを作成しました。それは、いくつかの拡張ツールバー、メニュー、テンプレートを Delphi 2006 (と 2005) に追加します。CFBH は、新規の .NET CF プロジェクトを開き、Delphi IDE 内部でコンパイルすることを非常に容易にし、異なる種類のエミュレータを起動して、アプリケーションをエミュレータや Pocket PC に配布することも容易にします。また CFMH は、分かりやすい PDF マニュアルを含んでおり、WEB サイト上には分割された数個の包括的なビデオがダウンロード可能になっています。

    インストールと設定

1) Compact Framework プロジェクトプリプロセッサをダウンロードし、解凍してフォルダに配置します

2) Borland Developer Studio が閉じられていることを確認します

3) Compact Framework ビルドヘルパーをダウンロードして、セットアップを実行します

4) Settings (設定) : 結果として、CFBH のすべての機能が新しいメニュアイテムとして作成されるようにチェックボックスをチェックします

5) Folder Setup (フォルダセットアップ)

  • BDS 4.0 コンパイラとライブラリパスを参照するようにします
  • Auto Fix Errors をチェックし、Compact Framework プロジェクトプリプロセッサの MakeCFCompatibleDLL.DLL を参照するようにします
  • 他のオプションは、この記事の後のほうで説明します

Hide image
Click to see full-sized image

6) Emulators (エミュレータ)

  • これらの手順で、複数のエミュレータ、Windows Mobile イメージ、設定オプションを定義することが出来るようになっています。また、それぞれのエミュレータに対して個別の設定を保存できます
  • エミュレータと Windows Mobile イメージのパスを設定します
  • その他のタブシートの上では、画面解像度や、エミュレータスキン、ネットワークオプションなど が定義できます.
  • On the other tabsheets you can define the screen resolution, skin, network options, ...

Hide image
Click to see full-sized image

7) Deploy (配布)

  • Deploy ページでは、アプリケーションの配布のために1度だけ実行する、デフォルトの配布方法を設定します。

    CFHB を使った Delphi Pocket PC アプリケーションの 作成、コンパイルと配布

さあこれで、CFHB のインストールが完了しました、もう一度同じサンプル作成してみましょう。今回、アプリケーションのコンパイルと配布が非常にすばやく出来るようになっていることに注目するはずです。

1) ファイル | 新規作成 | その他 から、Smart Device Application を選択します

2) フォームの Text プロパティを次のように設定します : "Pocket PC"

3) Button を追加して、Text を次のように変更します : "Delphi"

4) CFBH ツールバーで、[Selected Emulator] をえらんでエミュレータを選択し、CFBH Run ボタンを押します。 選択されたエミュレータが開始されます。生成された EXE は自動的にエミュレータの共有フォルダにコピーされるため、開発者はエクスプローラを操作してストレージカードから EXE を実行できます。

5) Pocket PC が PC に接続され Microsoft ActiveSync が有効になっていることを確認します。 Active Sync (device)を選択して CFBH Run ボタンを押します。 開発者の新規アプリケーションは、接続されたモバイルデバイス上で自動的に起動されます。

Hide image
Delphi IDE and CFBH

すばらしくないですか? ソースコードを注意深く見ると、E2003 エラーが発生していた場所に変更が加えられていることに気づくはずです。CF というコンパイラディレクティブは、Compact Framework DCCIL コンパイラ使っているときに、このソースが Compact Framework DCCIL コンパイラによってこのソースがコンパイルされないコンパイラ指令 CF が加えられます。Compact Framework プロジェクトプリプロセッサCompact Framework ビルドヘルパーの組み合わせは、プロジェクトのコンパイル作業を本当によく補助してくれます。


    Oosterkamp クラス ヘルパー

このプリプロセッサの欠点は、1個のエラーが1行を超えるとき、1行のみがコメントアウトされ、すべて(のコード)がコンパイルされないアプリケーションという結果になります。すべての問題がプリプロセッサによって処理できるわけではないので、Jeroen PluimersOosterkamp クラスヘルパーを書きました。このクラス ヘルパーは、複数のプロパティやメソッドを (TextBox, TreeView, Toolbar, TrackBar, NumericUpDown, MainMenu, ImageList, Timer, DataGrid, Application, 等のような)既存の .NET CF クラスに対して追加を行います。

CFBH テンプレート( ファイル|新規作成|その他|Smart Device Application) で開始すると、1個の拡張ユニットが含まれています

{$IFDEF CF_Oosterkamp}
uses
OosterKamp.WindowsCE.ClassHelpers;
{$ENDIF CF_Oosterkamp}

このクラスヘルパーを使用するためには、いくつかの拡張コンパイルオプションを設定する必要があります。それらをリスト上で設定可能になっているので、CFBH Options|Folder setup で有効にします。

-DCF_Oosterkamp
-U"C:\Program Files\CFBuild2006\ClassHelpers"

アプリケーションをもう一度コンパイルしましょう。{$IFNDEF CF} コンパイラ指令がすべて消えているのに、気づくはずです。Oosterkamp クラス ヘルパーを使用することにより、InitializeComponentメソッドにあるすべてのプロパティは存在していますが、コメントアウトする必要はありません。いくつかは実装されますが、その他は見せ掛けのものです。

クラス ヘルパーユニットが含まれているとき、Auto Fix Preprocessor オプションを OFF にすることができます。通常、プリプロセッサを使うことなしに動作するほうがベターです。クラス ヘルパーに関する追加の情報を C:\Program Files\CFBuild2006\classhelpers に見つけることができます。

CFBH と Oosterkamp クラス ヘルパーを利用すると、Pocket PC アプリケーションは、手作業でいかなる変更を行うことなしに、コンパイルをできます。しかし、.NET framework と .NET CF の間には、他にも違いがあります。次のチャプターで、どのコントロールがサポートされているかということと、Pocket PC 上で快適に動作するコードをどのように記述するかを説明します。

    System.Windows.Forms


Hide image
Click to see full-sized image

    Forms

Pocket PC において、境界線付きのトップレベルのフォームは、常にフルスクリーンで表示され、移動したり大きさを変更することはできません。したがって、設計時における Size プロパティの適切な値は、Width=240; Height=320 です。実行時には SizeLocation のプロパティは無視されます。CFBH テンプレート (ファイル|新規作成|その他|Smart device) を使っているとき、フォームのサイズは自動的に設定されます。

共通の画面解像度は次の通りです :

 
176x220
240x320
320x240
240x240
480x480
640x480
Windows Mobile 5.0  
Windows Mobile 2003 SE  
     
Windows Mobile 2003  
       
Smart Phone 2003
         


Pocket PC 上で、フルスクリーンでないフォームを表示するために、フォームの FormBordorStyle プロパティを FormBorderStyle.None に設定する必要があります。close ボタンの位置は、いつでも右の角に位置付きます。

フォームを画面の中央に位置づけるために使うことができる StartPosition プロパティは、.NET CF ではサポートされません。しかし、これはフォームの Load イベントで画面の中央位置を計算するだけで簡単に解決されます。

procedure TWinForm1.TWinForm1_Load(sender: System.Object; e: System.EventArgs);
begin Self.Location := System.Drawing.Point.Create( (Screen.PrimaryScreen.Bounds.Width - Self.Width) div 2,
(Screen.PrimaryScreen.Bounds.Height - Self.Height) div 2);
end;

Pocket PC は通常、ユーザーが即座にアプリケーションを切り切り替えることが出来るようするため、期限なしに(メモリ上に)残ったまま動作します。そのため、Pocket PC アプリケーションは終了することなく、代わりに最小化されます。フォームプロパティ MinimizeBoxTrue(デフォルト)のとき、"smart minimize" X ボタンが右上に表示されます。MinimizeBox=False ならば小さい close OK ボタンが表示されます。 CFBH テンプレートを使っているときは、MinimizeBox プロパティは False になります。

X MinimizeBox=True Minimize
OK MinimizeBox=False Close


ウィンドウが最小化されるタイミングを捕捉したいなら、そのトリガーは Deactivate イベントです。

Pocket PC 上のアプリケーションを閉じるためには、設定 | システム | メモリ | 実行中のプログラム に移動します。すべてのアプリケーションのリストが表示されるので、その中から終了切り替えを行うことができます。

TabIndex プロパティは .NET CF には存在しません。タブ移動は Z オーダーを基本にしており、この順番は フォーム上のコントロールの集合に追加されます。Pocket PC アプリケーションで最初にフォーカスを持つのはメインフォームそのものです。

    ハードウェアボタン

Hide image
Hardware buttons

Pocket PC は5個のボタンを持つ方向パッドを持っています。それは、アプリケーションと操作するのに使用することができます。それらのキーの、キーイベントの補足は可能です。KeyDown イベントは、KeyCode プロパティを明らかにする KeyArgs を受け取ります。
KeyCode プロパティの値を比較するために、どのボタンが押されたかを見極めることができます。

procedure TWinForm1.TWinForm1_KeyDown(sender: System.Object; e: System.Windows.Forms.KeyEventArgs);
begin case e.KeyCode of Keys.Up : ... Keys.Down : ... Keys.Left : ... Keys.Right : ... Keys.Return : ... end;
end;

    Application

.NET で使用できる Application クラスのプロパティの大部分は、.NET CF では実装されていません。そのため、CommonAppDataPathExecutablePathCompanyNameProductNameProductVersionのようなプロパティは、有効ではありません。

実行形式のパスを取得するもうひとつの方法は、アセンブリの最初のモジュールの FullyQualifiedName プロパティにアクセスすることです。アセンブリオブジェクトにアクセスするために、System.Reflection名前空間 を追加する必要があります。ファイル入出力機能は System.IO 名前空間に含まれています。

uses
  ..., System.Reflection, System.IO;

strExecutableFullName := System.Reflection.Assembly.GetExecutingAssembly.GetModules[0].FullyQualifiedName;
strExecutableName := System.IO.Path.GetFileName(strExecutableFullName);
strExecutablePath := System.IO.Path.GetDirectoryName(strExecutableFullName);

アセンブリバージョン (=製品バージョン) プロジェクトファイルによって特定されます。Pocket PC アプリケーションバージョン番号は、アセンブリの GetName.Version プロパティを使用することによりアクセス可能です。

[assembly: AssemblyVersion('1.2.0.0')]
strProductVersion := System.Reflection.Assembly.GetExecutingAssembly.GetName.Version.ToString;

新しい Smart Device プロジェクト (CFBH テンプレート) で開始すると、Oosterkamp クラス ヘルパーの1つが追加されます。それらの恩恵のすべてに預かるためには、OosterKamp.WindowsCE.ClassHelpersExと呼ばれる2番目のユニットを追加します。

これらのクラスヘルパーユニットが追加されると、フル機能の NET framework のような Application プロパティに処理することができます。System.IO と System.Reflection 名前空間は必要とされません。

Label1.Text := Application.ProductName;
Label2.Text := Application.ProductVersion;
Label3.Text := Application.ExecutablePath;

    Menu、ListBox、ListView、TreeView と ToolBar

設計時に、Menu、ListBox、ListView、TreeView または ToolBar のアイテムを作成すると、AddRange メソッドで「未定義の識別子」エラー受け取るはずです。これは、代わりに Add または Insert メソッドを使うことにより簡単に解決することができます。

Oosterkamp クラスヘルパーを使うと、開発者は何も変更する必要はありません。クラスヘルパーの AddRange メソッド (Oosterkamp.WindowsCE.ClassHelpers ユニット) はこれを解決します。

Pocket PC では、メインメニューとツールバーは、画面の一番下に表示されます。

Self.MainMenu1.MenuItems.AddRange(TArrayOfSystem_Windows_Forms_MenuItem.Create(Self.MenuItemFile));
Self.MenuItemFile.MenuItems.AddRange(TArrayOfSystem_Windows_Forms_MenuItem.Create(Self.MenuItemClose));
Self.ListBox1.Items.AddRange(TArrayOfSystem_Object.Create('Item0', 'Item1')); Self.TreeView1.Nodes.AddRange(TArrayOfSystem_Windows_Forms_TreeNode.Create(
System.Windows.Forms.TreeNode.Create('Node0',
TArrayOfSystem_Windows_Forms_TreeNode.Create(
System.Windows.Forms.TreeNode.Create('Node00'),
System.Windows.Forms.TreeNode.Create('Node01'))),
System.Windows.Forms.TreeNode.Create('Node1',
TArrayOfSystem_Windows_Forms_TreeNode.Create(
System.Windows.Forms.TreeNode.Create('Node10')))));
Self.MainMenu1.MenuItems.Add(Self.MenuItemFile);
Self.MenuItemFile.MenuItems.Add(Self.MenuItemClose);

Self.ListBox1.Items.Add('Item0');
Self.ListBox1.Items.Add('Item1');
Self.TreeView1.Nodes.Insert(0,System.Windows.Forms.TreeNode.Create('Node0'));
Self.TreeView1.Nodes.Item[0].Nodes.Insert(0,System.Windows.Forms.TreeNode.Create('Node00'));
Self.TreeView1.Nodes.Item[0].Nodes.Insert(1,System.Windows.Forms.TreeNode.Create('Node01'));
Self.TreeView1.Nodes.Insert(1,System.Windows.Forms.TreeNode.Create('Node1'));
Self.TreeView1.Nodes.Item[1].Nodes.Insert(0,System.Windows.Forms.TreeNode.Create('Node10'));

Hide image
Items - IDE Hide image
Items - Emulator

 

    PictureBox

設計時に PictureBox でイメージを開いたとき、このイメージは XML ベースのリソースファイル (.RESX) に保存されます。

<data name="PictureBox1.Image" type="System.Drawing.Bitmap, System.Drawing, 
Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
Qk3OOgAAAAAAADYAAAAoAAAAZAAAADIAAAABABgAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAA49/g49/g
49/g49/g49/g49/g49/g49/g49/g49/g49/g49/g49/g49/g49/g49/g49/g49/g49/g49/g49/g49/g
...
</value>
</data>
このリソースファイルはプロジェクトファイル (.DPR) に含まれます。
{$R 'MainForm.TWinForm.resources' 'MainForm.resx'}

フォームの InitializeComponent メソッドの中で、ResourceManager オブジェクトが生成され、GetObject メソッドによって、リソースはアクセス可能になります。

var
  resources: System.Resources.ResourceManager;
begin
  resources := System.Resources.ResourceManager.Create(TypeOf('TWinForm'));
Self.PictureBox1.Image := (System.Drawing.Image(resources.GetObject('PictureBox1.Image')));
end;

これは .NET アプリケーションの中では機能し、.NET CF アプリケーションでもコンパイルされます。しかし、エミュレータや Pocket PC の上で実行中の EXE では、MissingManifestResourceException エラーを起こしてしまうでしょう。私は、いくつかの方法を試しましたが、リソースマネージャを使ってこの問題を解決する方法を見つけることができませんでした。クラスヘルパーもまたこの問題を解決することができません。

そのため、イメージを表示するための他の二つの方法を見つけました :

最初の方法は、ファイルからビットマップをロードすることです。これは、Bitmap クラスの Create メソッドでイメージファイルの名前を指定することができます。そして、ビットマップを生成し、PictureBoxImage プロパティにこのオブジェクトを割り当てます。.

var
  objBitmap : System.Drawing.Bitmap;
  strExecutablePath : String;
begin strExecutablePath := Path.GetDirectoryName(Assembly.GetExecutingAssembly.GetModules()[0].FullyQualifiedName); objBitmap := Bitmap.Create(strExecutablePath+'\MyBitmap.bmp');
Self.PictureBox1.Image := objBitmap;
end;

または、クラスヘルパーを使って短くします :

Self.PictureBox1.Image := Bitmap.Create(Path.GetDirectoryName(Application.ExecutablePath)+'\MyBitmap.bmp');
開発者の EXE に ビットマップを含めることも可能です。リソースファイルを使う代わりに、$R コンパイラ指令を使って、ビットマップをプロジェクトファイルに含めばければなりません。 [ プロジェクトに追加 ] メニュー項目をクリックすることと同じように可能です。

最初に、ストリームオブジェクト作成し、アセンブリGetManifestResourceStream メソッドを使って、ビットマップをこのストリームへ読み込まなければなりません。そして、ビットマップオブジェクトを作成し、作成パラメータにしたがって、ストリームへ流します。

{$R 'MyBitmap.bmp' 'MyBitmap.bmp'}

var
  objStream: System.IO.Stream;
  objBitmap : System.Drawing.Bitmap;
begin
  objStream := Self.GetType.Assembly.GetManifestResourceStream('MyBitmap.bmp');
objBitmap := Bitmap.Create(objStream);
Self.PictureBox1.Image := objBitmap;
end;

Hide image
Image - Emulator

    ImageList

ImageList クラスを使用するとき、私たちは PictureBox クラスを使うときと同じ問題に遭遇します。その上、イメージはデザイン時コレクションに追加されるますが、プロジェクトはコンパイルできないでしょう。
解決策は、設計時には ImageList の作成と接続だけを行い、実行時にファイル (またはリソース) からのイメージの読み出しとイメージインデックスの設定を行うことです。

procedure frmMain.frmMain_Load(sender: System.Object; e: System.EventArgs);
var strPath : String;
begin strPath := Path.GetDirectoryName(Application.ExecutablePath)+'\Images\';

// Add images from file to ImageList1 ImageList1.Images.Add(Bitmap.Create(strPath+'Open.bmp'));
ImageList1.Images.Add(Bitmap.Create(strPath+'Save.bmp'));
ImageList1.Images.Add(Bitmap.Create(strPath+'Info.bmp'));

// Linked to ImageList1 ToolBar1.Buttons[0].ImageIndex := 0; ToolBar1.Buttons[1].ImageIndex := 1; ToolBar1.Buttons[2].ImageIndex := 2; TreeView1.Nodes[0].ImageIndex := 0; TreeView1.Nodes[0].SelectedImageIndex := 0; TreeView1.Nodes[0].Nodes[0].ImageIndex := 2; TreeView1.Nodes[0].Nodes[0].SelectedImageIndex := 2; // Add images from file to ImageList2 ImageList2.Images.Add(Bitmap.Create(strPath+'Delphi2006.bmp'));
ImageList2.Images.Add(Bitmap.Create(strPath+'NETCF.bmp'));

// Linked to ImageList2 ListView1.Items[0].ImageIndex := 0; ListView1.Items[1].ImageIndex := 1; PictureBox1.Image := ImageList2.Images[0]; end;

Hide image
Click to see full-sized image

    MessageBox

Microsoft .NET クラスライブラリを見ると、オーバーライドメソッドされた 12個の Show メソッドをサポートする .NET MessageBoxクラスがあることが分かります。.NET Compact Framework では、それらのうちで、たった 3個っしか実装さていません。もし、その他のメソッドを使おうとすると、コンパイルエラーになってしまうでしょう。

エラー: E2250 指定された引数で呼び出すことのできるオーバーロード関数 'Show' が定義されていませんでした
そのため、この 3つの形式だけが動作します :
MessageBox.Show('Message', 'Caption', MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
MessageBox.Show('Message', 'Caption');
MessageBox.Show('Message');

    Timer

Time r コンポーネントを 設計時にフォームにドロップしたあとに、開発者がすべきことは、 InitializeComponent メソッドの中の Create メソッドの変更を行うだけです。container パラメータは、削除しなければなりません。クラスヘルパーを使うと、その必要はありません。
procedure TWinForm1.InitializeComponent;
begin Self.Timer1 := System.Windows.Forms.Timer.Create; //(Self.components); Self.Timer1.Enabled := True; Self.Timer1.Interval := 1000; Include(Self.Timer1.Tick, Self.Timer1_Tick); end;

procedure TWinForm1.Timer1_Tick(sender: System.Object; e: System.EventArgs);
begin Text := DateTime.Now.ToString; end;

    OpenFileDialog と SaveFileDialog

OpenFileDialogSaveFileDialog は、共に .NET Compact Framework でサポートされています。しかし OpenFileDialogは "マイドキュメント" フォルダに制限されます。明らかにこの制限は、ユーザが標準の「マイドキュメント」フォルダー下にだけ自分のファイルをまとめられるように、オペレーティングシステムによって課せられています。

Hide image
Dialogs - Emulator

    Microsoft.WindowsCE.Forms

.NET Compact Framework 専用のクラスもいくつかあります。それらはSystem.Net.SocketsSystem.Data.SqlServerCESystem.Net.IrDAMicrosoft.WindowsCE.Forms 名前空間に含まれています。

    .NET CF 1.0 アセンブリのインストール

Delphi 上でこれら .NET CF アセンブリを使う前に、開発者の PC でそのアセンブリを利用可能にする必要があります。なぜなら、それらのアセンブリに対応する .dcpil ファイルは、 C:\Program Files\Borland\BDS\4.0\lib\cf フォルダで利用可能ではないからです。 まず NET Compact Framework 1.0 SP3. をダウンロードします。これらの DLL を、開発者の PC にコピーする方法は2つあります :

ConvertGAC.bat

  • .NET CF を開発者の Pocket PC にインストール
  • GAC_ が付いている すべての DLL を、開発者の Pocket PC のグローバルアセンブリキャッシュから開発者の PC へコピー
  • GAC DLL の名前変更を行うこのバッチファイルを実行
copy GAC_Microsoft.VisualBasic_v7_0_5000_0_cneutral_1.dll microsoft.visualbasic.dll
copy GAC_Microsoft.WindowsCE.Forms_v1_0_5000_0_cneutral_1.dll microsoft.windowsce.forms.dll copy GAC_mscorlib_v1_0_5000_0_cneutral_1.dll mscorlib.dll copy GAC_System.Data_v1_0_5000_0_cneutral_1.dll system.data.dll copy GAC_System.Drawing_v1_0_5000_0_cneutral_1.dll system.drawing.dll copy GAC_System.Net.IrDA_v1_0_5000_0_cneutral_1.dll system.net.irda.dll copy GAC_System.Web.Services_v1_0_5000_0_cneutral_1.dll system.web.services.dll copy GAC_System.Windows.Forms.DataGrid_v1_0_5000_0_cneutral_1.dll system.windows.forms.datagrid.dll copy GAC_System.Windows.Forms_v1_0_5000_0_cneutral_1.dll system.windows.forms.dll copy GAC_System.Xml_v1_0_5000_0_cneutral_1.dll system.xml.dll copy GAC_System_v1_0_5000_0_cneutral_1.dll system.dll pause

ConvertCAB.bat

  • netcf.core.ppc3.ARM.cab (=.NET CF のインストレーションファイル) に含まれるすべてのファイルを解凍します
  • すべてのファイルをリネームして削除するこのバッチファイルを実行します
del NE8A18~1.000
del 0mscoree.001
del MSCORE~1.002
del cgacutil.003
del NETCF1~1.004
del NETCFA~1.005
del CALEND~1.006
del CHARIN~1.007
del CULTUR~1.008
del CULTUR~2.009
del REGION~1.010
ren mscorlib.011 mscorlib.dll
ren 00system.012 system.dll
ren SYSTEM~3.013 system.drawing.dll
ren SYC6B2~1.014 system.web.services.dll
ren SYSTEM~4.015 system.windows.forms.dll
ren SY9B57~1.016 system.windows.forms.datagrid.dll ren SY40C7~1.017 system.xml.dll ren SYSTEM~1.018 system.net.irda.dll ren SY4317~1.019 system.data.dll ren MICROS~2.021 microsoft.visualbasic.dll ren MICROS~3.020 microsoft.windowsce.forms.dll del NETCF_~1.999 pause

Microsoft.WindowsCE.Forms (または System.Windows.Forms.Datagrid) アセンブリからのクラスを使ったプロジェクトをコンパイル/リンクするとき、DCCILコンパイラの -lu パラメータを使って、このアセンブリを参照しなくてはなりません。

もし、.NET CF プロジェクトをコンパイルするために VBScript を使うときは、以下のパラメータを追加しなくてはなりません。

-lu"C:\Program Files\NET CF\Assemblies\Microsoft.WindowsCE.Forms.dll"
-lu"C:\Program Files\NET CF\Assemblies\System.Windows.Forms.DataGrid.dll"

CFBH を使っているときは、アセンブリパスのセットと、コンパイラオプションの変更をしなくてはなりません。

Hide image
CFBH - Compiler Options

 

    バージョン

もし、あなたの Pocket PC の Windows Mobile バージョンを調べたいときには、(スタートメニューから) 設定 | システム | バージョン情報へ移動します。Compact Framework のバージョンをチェックするには、Windows フォルダから CGACUTIL.EXE アプリケーションを実行します。

プログラム的にバージョンを正確に決定するために使うことができます。

Environment.OSVersion;
Environment.Version;

それ以外の Environment のプロパティとメソッドはコマンドラインに似ていますが、MachineName, GetFolderPath, GetCommandLineArgs (and Delphi equivalent ParamStr) などは .NET CF でサポートされません。

Compact Framework バージョン

CF 1.0 1.0.2268.0
CF 1.0 SP1 1.0.3111.0
CF 1.0 SP2 1.0.3316.0
CF 1.0 SP3 1.0.4292.0 (1.0.4292.2 for Windows Mobile 5.0)
CF 2.0 (Beta 2) 2.0.5056.0
CF 2.0 2.0.5238.0

Windows Mobile バージョン

Windows Mobile 2003 4.20.1081
Windows Mobile 2003 Second Edition 4.21.1088
Windows Mobile 5.0 5.1.1700

 

    入力パネル

Microsoft.WindowsCE.Forms アセンブリは、InputPanel、Message、MessageWindow など 3 個のクラスを含んでいます。入力パネルは、Pocket PC の SIP (ソフトウェア入力パネル) のプログラム的な制御を提供します。

SIP は、Pocket PC のタスクバーから有効にできます。.NET CF ベースのアプリケーションでは、MainManu コンポーネントと関連付いているフォームがアクティブであるときだけ、タスクバーは表示されます。MainMenuフォームに追加したとき、SIP は自分で生成しなくても自動的に実行時の EXE 上に表示されます。そのため、Pocket PC のユーザは、テキストボックスや他の入力コントロールに入力するために、この仮想的なキーボードへのアクセスを持っています。

SIP の制御やポップアップを行いたいときは、コントロールが入力フォーカスを受け取ったときに、InputPanel オブジェクトを生成しなくてはなりません。したがって、開発者は、Microsoft.WindowsCE.Forms をフォームの uses 節に追加しなくてはなりません。TextBox の GotFocusLostFocus イベントでは、SIP の (popup を)有効にしたり、無効にしたりできます。

uses
  ..., Microsoft.WindowsCE.Forms;

procedure TWinForm.InitializeComponent;
begin MainMenu1 := System.Windows.Forms.MainMenu.Create; Self.Menu := MainMenu1; Self.InputPanelMain := Microsoft.WindowsCE.Forms.InputPanel.Create; Self.TextBox1 := System.Windows.Forms.TextBox.Create; Include(TextBox1.GotFocus, TextBox1_GotFocus); Include(TextBox1.LostFocus, TextBox1_LostFocus); end;

procedure TWinForm.TextBox1_GotFocus(Sender: TObject; Args: System.EventArgs);
begin InputPanelMain.Enabled := True; end;

procedure TWinForm.TextBox1_LostFocus(Sender: TObject; Args: System.EventArgs);
begin InputPanelMain.Enabled := False; end;

Hide image
InputPanel - Emulator

SIPが有効にされるか、またはユーザかプログラムに基づいてのどちらか無効にされるときはいつも、EnabledChanged イベントは起こります。 開発者ははいくつかのコントロールを動くか、またはリサイズすることによって形式のレイアウトを再配列するこの出来事の引き金となることができます。SIP のサイズを取得するには、Bounds プロパティにアクセスすることです。SIP によって占有されなかったフォーム領域のサイズを測定するために、開発者は VisibleDesktop プロパティを使用しなければなりません。

Bounds プロパティは、Pocket PC に対して常に、width が 240 ピクセルと height が 80 ピクセル という値を返します。SIP が有効にされるかどうかにかかわらず。 SIP が無効であるときは、MmainMenu には 26 ピクセルの高さがあるのを考慮に入れなければなりません。

これは、画面の下部に TextBox を位置づける方法のサンプルです。

procedure TWinForm.InitializeComponent;
begin Self.InputPanelMain := Microsoft.WindowsCE.Forms.InputPanel.Create; Include(InputPanelMain.EnabledChanged, InputPanelMain_EnabledChanged); end;

procedure TWinForm.InputPanelMain_EnabledChanged(Sender: TObject; Args: System.EventArgs);
begin if InputPanelMain.Enabled then Self.TextBox1.Top := InputPanelMain.VisibleDesktop.Height - Self.TextBox1.Height - 2 else Self.TextBox1.Top := InputPanelMain.VisibleDesktop.Height - Self.TextBox1.Height - 26 - 2; end;

皆さんは、恐らくこのように考えるでしょう : 「クラスヘルパーを使えばもっと簡単にできるのではないか。」 もちろん、そのとおり。InputPanel クラスに対応するクラスヘルパーは 3 つの新しいメソッドを追加します。

procedure HookTextBoxBase(TextBoxBase: System.Windows.Forms.TextBoxBase);
procedure HookAllTextBoxBases(ContainerControl: System.Windows.Forms.Control);
procedure HookTextBoxBases(TextBoxBases: array of System.Windows.Forms.TextBoxBase);

Hide image
CFBH - Templates

CFBH を使って、「Portrait form with Input Panel」 または 「Landscape form with Input Panel」テンプレートで開始するとMainMenu と InputPanel コンポーネントが設計時に追加されます。実行時には、HookAllTextBoxBases メソッドが、フォーム上のすべての TextBox の GotFocus と LostFocus イベントをフックするために呼び出されます。そのため、開発者はいかなる追加のコードを書くする必要はなく、ただこれらのテンプレートのうちの1つを使って開始し、すべての TextBox で SIP 動作するようにするだけです。

    System.IO

これは、System.IO のいくつかのクラス (Path, FileInfo) のメソッドの使い方の小さなサンプルです。この手順は、実行可能ファイルに関してのいくつかのシステム情報 (パス、バージョン、ファイルサイズ、作成時間 等)を検索します。

var
  objFileInfo : System.IO.FileInfo;
  strExecutableFullName : String;
strExecutableName : String;
strExecutablePath : String;
strProductVersion : String;
intFileSize : Integer;
strFileCreationTime : String;
begin strExecutableFullName := System.Reflection.Assembly.GetExecutingAssembly.GetModules[0].FullyQualifiedName; strExecutableName := System.IO.Path.GetFileName(strExecutableFullName); strExecutablePath := System.IO.Path.GetDirectoryName(strExecutableFullName); strProductVersion := System.Reflection.Assembly.GetExecutingAssembly.GetName.Version.ToString; objFileInfo := System.IO.FileInfo.Create(strExecutableFullName); try intFileSize := objFileInfo.Length; strFileCreationTime := objFileInfo.CreationTime.toString; //... finally objFileInfo.Free; end;
end;

 

    System.Net

System.Net 名前空間では、DNS という名前の static なクラスを見つけることでしょう。それは、インターネットドメインネームシステムから特定のホストに関する情報を検索します。 ユーザの Pocket PC の名前を得るのに GetHostNameメソッド を使用することができます。

GetHostByName メソッドを使うとき、結果は IPHostEntry クラスのインスタンスで返されます。IPHostEntry は複数の IP アドレスと別名を含んでいます。リストにおける最初のアドレスにアクセスすることによって、あなたはあなたの Pocket PC の IP アドレスを得ることができます。それが 127.0.0.1 と異なっているときは、あなたには、ネットワーク接続 (クレードル と ActiveSync 稼働か WiFi 接続) があるでしょう。

uses 
...,
System.Net; var objIPHost : System.Net.IPHostEntry; strHostName : String;
strHostIP : String;
begin strHostName := DNS.GetHostName; objIPHost := DNS.GetHostByName(strHostName); strHostIP := objIPHost.AddressList[0].ToString; end;


    System.Data

一般に、テキストや INI ファイルと Windows レジストリは .NET アプリケーションにとって過去のものです。 XMLファイルはデータを保存する適切な方法です。かなり複雑に見える多くのクラスがあ るSystem.XML 名前空間があります。 幸い、これを解決するために、非常に簡単な方法が .NET にあります。それは、System.Data 名前空間における Dataset のクラスです。 Delphi 開発者はデータをローカルに格納することができる ClientDataSet に間違いなく詳しいからです。そうです、この Dataset クラスは殆ど同程度の機能を持つメモリデータセットです。

    XML の読み書き

この例では、わずか数行のコードで、開発者が如何に容易にデータセット ( 1個のテーブルと整数インデックスフィールドと文字列型の説明フィールドがある) を作成することができるかを示して、XMLファイルをロードし、XMLファイルにデータセットコンテンツを保存できることを示します。

function TWinForm.GetExecutablePath : String;
begin Result := System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly.GetModules()[0].FullyQualifiedName); end;

procedure TWinForm.CreateDataset;
var DataTable1: DataTable; begin // Dataset1 has been created in design-time DataTable1 := Dataset1.Tables.Add('Table1');
DataTable1.Columns.Add('Index', typeof(Integer));
DataTable1.Columns.Add('Description', typeof(String));
end;

procedure TWinForm.LoadDataset;
var strFileName : String;
begin strFileName := GetExecutablePath + '\Dataset.xml';
if (System.IO.File.Exists(strFileName)) then Dataset1.ReadXML(strFileName); end;

procedure TWinForm.SaveDataset;
begin Dataset1.WriteXML(GetExecutablePath + '\Dataset.xml');
end;

The XML file could look like this :

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<Table1>
<Index>0</Index>
<Description>Borland</Description>
</Table1>
<Table1>
<Index>10</Index>
<Description>Delphi</Description>
</Table1>
<Table1>
<Index>20</Index>
<Description>.NET CF</Description>
</Table1>
</NewDataSet>

    位置付け機能

もし、いわゆる「位置づけ」機能を知りたいのなら、Rows コレクションの Find メソッドを使うべきです。この Find メソッドは 単一の DataRow オブジェクトを返します。このメソッドは、使用する前に DataTable オブジェクトの PrimaryKey プロパティをセットしておくすることを必要とします。セットをしないと、例外を受け取ります。

procedure TWinForm.CreateDataset;
var DataTable1: DataTable; arrPrimKey : array[0..0] of DataColumn;
begin DataTable1 := Dataset1.Tables.Add('Table1');
DataTable1.Columns.Add('Index', typeof(Integer));
DataTable1.Columns.Add('Description', typeof(String));

arrPrimKey[0] := DataTable1.Columns.Item['Index'];
DataTable1.PrimaryKey := arrPrimKey;
end;

procedure TWinForm.LoadDataset;
var strFileName : String;
arrPrimKey : array[0..0] of DataColumn;
begin strFileName := GetExecutablePath + '\Dataset.xml';
if (System.IO.File.Exists(strFileName)) then begin Dataset1.ReadXML(strFileName); arrPrimKey[0] := Dataset1.Tables.Item['Table1'].Columns.Item['Index'];
Dataset1.Tables.Item['Table1'].PrimaryKey := arrPrimKey;
end;
end;

function TWinForm.FindDescription(const aintIndex : Integer) : String;
var objRow : DataRow; begin Result := '';
objRow := Dataset1.Tables.Item['Table1'].Rows.Find(aintIndex);
if Assigned(objRow) then Result := objRow.Item['Description'].ToString;
end;

    XSD schema

また、ADO.NET Dataset のさらなるパワーを使用するのも可能です。Dataset とそれに含まれる DataTable には、多くの拡張 ColumnConstraints のプロパティがあります。そして、XSD Schema としてそれらは格納することができます。.NET CF の WriteXML メソッドは、WriteSchema がオプション (XML ファイルの中のインライン XSD Schema) であるとサポートしませんが、Dataset のクラスは利用可能な WriteXMLSchemaReadXMLSchema メソッドを持っています。

Hide image
ADO.NET Dataset

さてこれで、開発者は、データと XSD ファイルとして XML ファイルをリレーショナル構造でセーブしたりでロードしたりすることによって、ローカルファイルに基づく小さいデータベースアプリケーションを作成することができます。

procedure TWinForm.CreateDataset;
var DataTable1: DataTable; arrPrimKey : array[0..0] of DataColumn;
begin DataTable1 := Dataset1.Tables.Add('Table1');
with DataTable1.Columns.Add('Index', typeof(Integer)) do begin Unique := True; AutoIncrement := True; AutoIncrementStep := 10; end;
with DataTable1.Columns.Add('Description', typeof(String)) do MaxLength := 50; arrPrimKey[0] := DataTable1.Columns.Item['Index'];
DataTable1.PrimaryKey := arrPrimKey;
end;

procedure TWinForm.LoadDataset;
var strFileName : String;
begin strFileName := GetExecutablePath + '\Dataset.xsd';
if (System.IO.File.Exists(strFileName)) then begin Dataset1.ReadXMLSchema(strFileName); strFileName := GetExecutablePath + '\Dataset.xml';
if (System.IO.File.Exists(strFileName)) then Dataset1.ReadXML(strFileName); end;
end;

procedure TWinForm.SaveDataset;
begin Dataset1.WriteXML(GetExecutablePath + '\Dataset.xml');
Dataset1.WriteXMLSchema(GetExecutablePath + '\Dataset.xsd');
end;

    ライブテンプレート

私は、Delphi 2006 のライブテンプレートがとてもお気に入りなので、LoadDataset と SaveDataset メソッド用の 2 個のテンプレートを見せようと思います。 これらの XML ファイルを C:\Program Files\Borland\BDS\4.0\Objrepos\code_templates\delphi フォルダに追加してください。LoadDatasetSaveDataset をタイプします、そして、CTRL+J を押して、ライブテンプレートを呼び出してください。 パラメータ間の移動がタブキーで行えるはずです。

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
<template name="LoadDataset" invoke="manual">
<description>Load dataset from local XML/XSD file</description>
<author>Stefan Cruysberghs, http://www.scip.be</author>
<point name="FileNameDataset">
<text>MyDataset</text>
<hint>Filename (and folder) of local dataset (without extension XML/XSD)</hint>
</point>
<point name="VarFileName">
<text>strFileName</text>
<hint>Variable to store filename</hint>
</point>
<point name="Dataset">
<text>Dataset1</text>
<hint>ADO dataset object</hint>
</point>
<script language="Delphi" onenter="false" onleave="true">
DeclareVariable(|VarFileName|); </script> <code language="Delphi" delimiter="|"><![CDATA[ |VarFileName| := string(Path.GetDirectoryName(Application.ExecutablePath) + '\|FileNameDataset|.xsd');
if (System.IO.File.Exists(|VarFileName|)) then
begin
|Dataset|.ReadXMLSchema(|VarFileName|);
|VarFileName| := string(Path.GetDirectoryName(Application.ExecutablePath) + '\|FileNameDataset|.xml');
if (System.IO.File.Exists(|VarFileName|)) then
|Dataset|.ReadXML(|VarFileName|);
end;
|end|]]></code>
</template>
</codetemplate>
<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
<template name="SaveDataset" invoke="manual">
<description>Save dataset to local XML/XSD file</description>
<author>Stefan Cruysberghs, http://www.scip.be</author>
<point name="FileNameDataset">
<text>MyDataset</text>
<hint>Filename (and folder) of local dataset (without extension XML/XSD)</hint>
</point>
<point name="Dataset">
<text>Dataset1</text>
<hint>ADO dataset object</hint>
</point>
<code language="Delphi" delimiter="|"><![CDATA[ |Dataset|.WriteXML(Path.GetDirectoryName(Application.ExecutablePath) + '\|FileNameDataset|.xml');
|Dataset|.WriteXMLSchema(Path.GetDirectoryName(Application.ExecutablePath) + '\|FileNameDataset|.xsd');


|end|]]></code>
</template>
</codetemplate>

    DataGrid

DataTable のデータを表示する最も簡単な方法は DataGrid を追加することです。しかし、DataGrid コンポーネントをフォーム上に追加すると、次のようなエラーを受け取るはずです :

エラー: E2003 未定義の識別子: 'DataGrid'


また、DataGrid コンポーネントは .NET CF に存在していますが、それは System.Windows.Forms.dll ファイルに含まれていません。 それは. NET CF アセンブリ System.Windows.Forms.DataGrid.dll に含まれています。したがって、開発者は DCCILコンパイラのパラメータか CFBH のコンパイラオプションで、このアセンブリへの参照をしなければなりません。

-lu"C:\Program Files\NET CF\Assemblies\System.Windows.Forms.DataGrid.dll"

.NET CF の DataGrid コンポーネントは、.NET に通常あるような高度な編集機能を提供しません。また、DataMember プロパティと SetDataBinding メソッドは存在していません。DataGrid は、複数の DataTable オブジェクトからの行の表示を処理することができません。そのため、DataSetDataGrid.DataSource プロパティ接続するかわりに DataTable 接続することで問題を解決します。

Self.DataGrid1.DataSource := Self.DataSet1.Tables['Table1'];

    CAB ファイルへのパッケージングと配布

あなたのアプリケーションを配布するために、開発者は Windows のモバイルベースのデバイスにインストールのためにアプリケーションをパッケージして、展開のためにそれを公認する必要があります。 Windows の Mobile SDK をインストールしたとき、CAB ウィザード (CabWiz.exe) と呼ばれるアプリケーションを見つけると思います。 このコンソールアプリケーションは、入力パラメータとして INF ファイルを必要とします。

INF ファイルは、元になるファイル(exe、アセンブリ、画像、メディア、xml)、インストール先フォルダー、登録キー、ショートカットなどの、アプリケーションのインストール指令について説明します。CAB ファイルがいったん作成されると、ユーザーは Pocket PCにそれをコピーするだけでよいです。 ただそれをダブルクリックしてください。そうすれば、ユーザーのアプリケーションは自動的にインストールされます。

この CAB ウィザードに関する詳しい情報、利用可能なセクション、および変数、ディレクトリ識別子などは、SDK ヘルプファイルで調べることができます。

[Version]
Signature   = "$Windows NT$"        
Provider    = "SCIP.be Stefan Cruysberghs"
CESignature = "$Windows CE$"        
 
[CEStrings]
AppName     = "ShowImageList"       
InstallDir  = %CE1%\%AppName%       ; Program Files\ShowImageList
 
[SourceDisksNames]                  ; directory that holds the application's files
1 = , "Common Files",,
 
[SourceDisksFiles]                  ; list of files to be included in .cab
ShowImageList.exe = 1
Open.bmp = 1
Save.bmp = 1
Info.bmp = 1
Delphi2006.bmp = 1
NETCF.bmp = 1
 
[DefaultInstall]                   ; operations to be completed during install
CopyFiles   = CopyToProgramFiles, CopyToImages
CEShortcuts = Shortcuts   
 
[DestinationDirs]                   ; default destination directories for each operation section
CopyToProgramFiles = 0, %InstallDir%
CopyToImages = 0, %InstallDir%\Images
Shortcuts   = 0, %CE11%             ; \Windows\Start Menu\Programs
 
[CopyToProgramFiles]                ; copy operation file list
"ShowImageList.exe", ShowImageList.exe

[CopyToImages]                      ; copy operation file list
"Open.bmp", Open.bmp
"Save.bmp", Save.bmp
"Info.bmp", Info.bmp
"Delphi2006.bmp", Delphi2006.bmp
"NETCF.bmp", NETCF.bmp
 
[Shortcuts]                         ; Shortcut created in destination dir, %CE11%
%AppName%,0,ShowImageList.exe

    結び

Delphi .NET CF コンパイラとすべての Pocket PC 機能を探検するのは、とてもエキサイティングです。 Delphi 2006 とても安定していて非常に高速で、私はこの IDE の新しい機能 (チェンジバー、Live Template、ヒストリなど)が大好きです。Jeremy North と Chee Wee Chua は、いくつかの使いやすいプラグインやツールなどの作成というすばらしい仕事をしました。そして、特に Jeroen Pluimers によって書かれた Oosterkamp クラスヘルパー はとても役に立ちます。それらを使用することによって、あなたは .NET WinForm デザイナによって生成されたコードもほとんど少しも変更する必要はありません。また、すべての Code Insight の機能があなたを助けることができるようにライブラリパスを変えるのを忘れないでください。小さい Pocket PC アプリケーションを書かなければならないなら、もはや、これらのプラグインを利用して Delphi 2006 を使うことをためらわないでください!

私はすでに、予定されている次の Delphi のリリース (コードネーム Highlander) が .NET CF デザイナを伴っていることをとても楽しみにしています。Delphi ロードマップによると、.NET CF デザイナは WinForm ではなく、VCL をベースにするでしょう。VCL コントロールが標準の .NET CF がコントロールよりも強力になことを確信しています。 Delphi の未来は明るく見えています。

     著者について

Stefan Cruysberghs は ベルギー人のソフトウェエア開発者で、多くの Delphi コンポーネント、ツール、記事を執筆しています。その他の情報は、彼のパーソナルWebサイトで見ることができます : http://www.scip.be.





Server Response from: ETNASC03