Ink Blog サンプル アプリケーションでは、手描き入力機能を備えたマネージド UserControl クラスを作成し、Microsoft Internet エクスプローラーでそのコントロールをホストする方法を示します。 また、このサンプルでは、HTTP を使用してネットワーク経由でインク データを送信し、サーバーにインクを保持する方法の 1 つも示しています。
Note
このサンプルを実行するには、ASP.NET がインストールされたMicrosoft インターネット インフォメーション サービス (IIS) が必要です。 コンピューターでアプリケーションを実行するために必要な要件 ASP.NET 満たしていることを確認します。
Note
Microsoft Windows XP Tablet PC Edition Development Kit 1.7 がインストールされているタブレット以外の PC コンピューターでこのサンプルを実行した場合、インク タイトルのテキスト認識機能は機能しません。 これは、タブレット PC SDK 1.7 がインストールされているタブレット PC 以外のコンピューターに認識エンジンがないために発生します。 アプリケーションの残りの部分は、説明に従って実行されます。
概要
Ink ブログ サンプルでは、インク対応 Web ログを作成します。 InkBlogWeb は、ASP.NET アプリケーションです。 インク 入力は、ASP.NET ページから参照されるユーザー コントロールによって実現されます。
ユーザー コントロールは、タブレット PC プラットフォーム コンポーネントがクライアント コンピューターにインストールされているかどうかを検出します。 その場合、ユーザー コントロールは、Web ページ上の 2 つのインク対応領域 (ブログ エントリのタイトルのインク入力用と、エントリの本文用) をユーザーに表示します。 タブレット PC プラットフォーム コンポーネントがインストールされていない場合、ユーザーには、エントリのタイトルと本文の標準テキスト ボックス コントロールが与えられます。
ユーザーがエントリの作成を完了すると、[ブログの追加] ボタンがクリックされ、投稿が保存のために Web サーバーに送信されます。 サーバーでは、タイトル テキストと投稿日、およびグラフィックス交換形式 (GIF) ファイルへの参照がアプリケーションによって保存されます。 サーバーにも保存された GIF ファイルには、強化された GIF ファイル内の本文のインク データが含まれています。 強化された GIF 形式の詳細については、「 HTML でのインクの格納」を参照してください。
InkBlog ソリューションには、 InkBlogControls プロジェクトと InkBlogWeb プロジェクトの 2 つのプロジェクトがあります。
InkBlogControls プロジェクト
InkBlogControls プロジェクトは、Web ページでの手描き入力を有効にするユーザー コントロールのコードを含む UserControl プロジェクトです。 このコントロールのコード InkArea コントロールは、InkArea.cs ファイルにあります。
クラスは InkAreaUserControl クラスから継承されます。 コントロールのコンストラクターは、InkAreaCreateInkCollectionSurfaceヘルパー メソッド を呼び出します。
public InkArea()
{
// Standard template code
try
{
inputArea = CreateInkCollectionSurface();
}
catch (FileNotFoundException)
{
inputArea = new TextBox();
((TextBox)inputArea).Multiline = true;
}
inputArea.Size = this.Size;
// Add the control used for collecting blog input
this.Controls.Add(inputArea);
}
メソッドは CreateInkCollectionSurface 、 InkCollector クラスのインスタンスを作成しようとすることによって、タブレット PC のインク コンポーネントをクライアントで使用できるかどうかを判断します。 メソッドの呼び出しが CreateInkCollectionSurface 成功した場合、メソッドは Panel オブジェクトをコントロールとして返します。
protected Control CreateInkCollectionSurface()
{
try
{
Panel inkPanel = new Panel();
inkPanel.BorderStyle = BorderStyle.Fixed3D;
inkCollector = new InkCollector(inkPanel);
((InkCollector)inkCollector).Enabled = true;
return inkPanel;
}
catch
{
throw;
}
}
インク プラットフォーム ファイルが見つからないためにコンストラクターが失敗した場合、InputAreaコントロールは InkCollector コントロールではなく TextBox コントロールとしてインスタンス化されます。 コンストラクターは、コントロールのサイズを親ユーザー コントロールのサイズに変更し、親の Controls コレクションに追加します。
InkArea コントロール クラスは、InkData、TextData、WebEnabled の 3 つの興味深いパブリック プロパティを実装します。
InkData プロパティは読み取り専用であり、クライアントがインク処理をサポートしている場合は、シリアル化されたインク データにアクセスできます。 クライアントがインク処理をサポートしていない場合、InkData プロパティは空の文字列を取得します。 InkData プロパティは、ヘルパー メソッド SerializeInkData を呼び出して、クライアントが手描き入力をサポートしているかどうかを判断します。
protected String SerializeInkData()
{
Debug.Assert(InkEnabled, null, "Client must be ink-enabled");
// Obtain the ink associated with this control
Ink ink = ((InkCollector)inkCollector).Ink;
// Serialize the ink
if (ink.Strokes.Count > 0)
{
byte[] inkDataBytes = ink.Save(PersistenceFormat.Gif);
return Convert.ToBase64String(inkDataBytes);
}
// Default to returning the empty string.
return String.Empty;
}
SerializeInkDataメソッドでは、Ink オブジェクトを取得するときに InkCollector へのキャストが必要になります。これは、 が Control として宣言されているためinputAreaです。 Ink オブジェクトにストロークが含まれている場合、インク データは GIF (PersistenceFormat 列挙値を使用して指定) としてバイト配列に保存されますinkDataBytes。 次に、 メソッドはバイト配列を Base64 でエンコードされた文字列に変換し、この文字列を返します。
クライアントが認識を実行できると仮定すると、 プロパティは TextData 、インク データを手書き認識エンジンに渡すことから RecognitionResult オブジェクトを返します。 クライアントがインク対応でない場合は、次のコードに示すように、テキスト ボックスの内容が返されます。
public string TextData
{
get
{
if (this.WebEnabled)
{
return RecognizeInkData();
}
else
{
return ((TextBox)inputArea).Text;
}
}
}
プロパティは TextData 、認識を実行するために、 RecognizeInkData次のコードに示すヘルパー メソッド を呼び出します。 認識エンジンがシステムに存在する場合、 RecognizeInkData このメソッドは RecognitionResult オブジェクトの TopString プロパティを含む文字列を返します。 それ以外の場合は、空の文字列を返します。
protected String RecognizeInkData()
{
// Obtain the ink associated with this control
Ink ink = ((InkCollector)inkCollector).Ink;
if (ink.Strokes.Count > 0)
{
// Attempt to create a recognition context and use it to
// retrieve the top alternate.
try
{
RecognizerContext recognizerContext = new RecognizerContext();
RecognitionStatus recognitionStatus;
recognizerContext.Strokes = ink.Strokes;
RecognitionResult recognitionResult = recognizerContext.Recognize(out recognitionStatus);
if (recognitionStatus == RecognitionStatus.NoError) && ( null != recognitionResult) )
{
return recognitionResult.TopString;
}
}
catch (Exception)
{
// An exception will occur if the client does not have
// any handwriting recognizers installed on their system.
// In this case, we default to returning an empty string.
}
}
return String.Empty;
}
プロパティは InkEnabled 、クライアント コンピューターで手描き入力がサポートされているかどうかを示す読み取り専用のブール値です。
コントロール クラスの InkArea もう 1 つの重要なパブリック メンバーは、 DisposeResources メソッドです。 このメソッドは、 メソッドを Dispose 内部的に呼び出して、ユーザー コントロールによって利用されるすべてのリソースがクリーンアップされるようにします。 コントロールを InkArea 使用するアプリケーションは、コントロールの使用が DisposeResources 完了したら、 メソッドを呼び出す必要があります。
InkBlogWeb プロジェクト
InkBlogWeb プロジェクトは、ブログ機能を提供するためにコントロールを InkArea 参照する Web セットアップ配置プロジェクトです。 Web セットアップ配置プロジェクトの詳細については、「Web セットアップ プロジェクトの配置」を参照してください。
ブログ サンプルを実装する .aspx ファイルには、Default.aspx と AddBlog.aspx の 2 つがあります。 Default.aspx は InkBlogWeb アプリケーションの既定のページです。 このページの分離コード ファイルは Default.aspx.cs です。 このページには、新しいブログ エントリ フォームを含むページへのリンクが表示され、既存のブログ エントリが表示されます。 このプロセスは、新しいブログ入力フォーム ページ AddBlog.aspx を次に示した後で説明します。
AddBlog.aspx とその分離コード ファイル AddBlog.aspx.cs には、新しいブログ エントリを作成するためのロジックとユーザー インターフェイス コードが含まれています。 AddBlox.aspx は、次の例に示すように、HTML OBJECT 要素を使用して InkBlogControls プロジェクトで作成された InkArea コントロール クラスの 2 つのインスタンスを参照します。 1 つのインスタンスには id inkBlogTitle の属性があり、もう 1 つのインスタンスには inkBlogBody の id 属性があります。
<OBJECT id="inkBlogTitle" classid="InkBlogControls.dll#InkBlog.InkArea" width="400" height="48" VIEWASTEXT>``</OBJECT>``<br/>``<OBJECT id="inkBlogBody" classid="InkBlogControls.dll#InkBlog.InkArea" width="400" height="296" VIEWASTEXT>``</OBJECT>
InkBlogControls.dll アセンブリは、それを参照している .aspx ページと同じディレクトリに存在する必要があります。 Web セットアップ展開プロジェクトでは、デプロイ プロジェクトに "InkBlogControls からのプライマリ出力" 項目が存在することが証明されているように、これが確実に当たります。
タイトル コントロールは、タイトルの 1 行のインクの入力を容易にするために、高さが 48 ピクセルのみです。 ボディ コントロールは高さ 296 ピクセルで、複数の行や図面のより大きなブログ エントリを格納できます。
InkArea コントロールは、標準の HTML BUTTON 要素の onclick イベント ハンドラーを使用して、クライアント側スクリプト関数 AddBlog に接続されます。
<button id="BUTTON1" type="button" onclick="AddBlog()">Add Blog</button>
ページには、BlogTitleText、BlogBodyText、BlogBodyInkData の 3 つの非表示の INPUT 要素を含む HTML フォームもあります。 このフォームは、ブログエントリデータをサーバーにポストバックするために使用されます。 AddBlog.aspx は、フォームに対して定義されたポストバック ハンドラーです。
Microsoft JScript<エンティティ type="reg"/>-extracts で記述された AddBlog 関数は、InkArea コントロールからブログ データを抽出し、結果をサーバーに投稿します。
function AddBlog()
{
// Extract the blog's title data as ink and text
form.BlogTitleText.value = inkBlogTitle.TextData;
// Extract the blog's body data as ink and text
form.BlogBodyText.value = inkBlogBody.TextData;
form.BlogBodyInkData.value = inkBlogBody.InkData;
form.submit();
}
データがサーバーに到着すると、AddBlog.aspx.cs のコードによって、Page_Load イベント ハンドラーがチェックされ、HttpRequest オブジェクトの Form プロパティにデータが含まれているかどうかを確認します。 その場合は、現在のシステム時刻に基づいてファイル名を作成し、フォーム データを 3 つの文字列変数に格納し、次のコードに示すように、データを HTML ファイルとインク データを含む GIF ファイル (存在する場合) に書き込みます。
if ( (String.Empty != inkBody) )
{
// Use helper method to create a GIF image file from ink data
CreateGif(imagePath, fileName, inkBody);
// Create an HTML fragment to reference the image file
content = "<img src=\"Blogs/Images/" + fileName + ".gif\"></img>";
}
else
{
// If no ink data is available create an HTML fragment that contains
// the blog's text directly.
content = "<P>" + textBody + "</P>";
}
// Use helper method to create the blog web page on the server
CreateHtm(blogPath, fileName, blogTitle, content);
ヘルパー メソッドの詳細については、サンプル ソース コードを参照してください。
サンプルの実行
Tablet PC SDK 1.7 では、Ink Blog Web サンプルが既定でインストールされます。 サンプルを実行するには、インターネット エクスプローラーで に移動します。https://localhost/TabletPCSDK_WebSamples/InkBlogWeb/Default.aspx. Windows Server 2003 を実行している場合は、コンピューター名を "localhost" に置き換えます。
Note
コンパイルされた Web サンプルは、SDK の既定のインストール オプションではインストールされません。 カスタム インストールを完了し、"事前コンパイル済み Web サンプル" サブオプションを選択してインストールする必要があります。
Microsoft Visual Studio<エンティティ type="reg"/> .NET でプロジェクトを開いてビルドし、IIS を実行している別のコンピューターに展開して、サンプルを実行することもできます。
サンプルのトラブルシューティング
サンプルを実行またはホストするときに問題が発生する可能性がある 3 つの領域は、アクセス許可と認識です。
アクセス許可
このサンプルでは、新しいブログ エントリを作成しようとしているアカウントの仮想ルート フォルダー内の書き込みアクセス許可が必要です。 既定では、Tablet PC SDK 1.7 で提供されるサンプルのコンパイル済みバージョンには、この要件を満たすために正しいアクセス許可が設定されています。
提供された Web セットアップ配置プロジェクトを使用してサンプルをビルドして展開する場合は、InkBlogWeb 仮想ルートが指すファイル システム フォルダー (C:\InetPub\WWWRoot\InkBlogWeb など) への書き込みアクセス権を %MACHINENAME%\Users グループに付与する必要があります。 Users グループには IIS で使用される匿名アカウントが含まれるため、ASP.NET アプリケーションは新しいブログ エントリをファイル システムに書き込みます。 別の方法として、仮想ルートへの匿名アクセスを削除し、認証を強制します。
認識
ブログのタイトルでインクを認識するには、手書き認識エンジンをインストールする必要があります。 Windows XP Tablet PC Edition 以外のオペレーティング システムを搭載し、Tablet PC SDK 1.7 がインストールされているコンピューターから InkBlog アプリケーションにアクセスする場合は、InkArea コントロールにインクで記述できますが、認識エンジンは存在せず、ブログ エントリのタイトルは表示されません。 ただし、本文のインク コンテンツは引き続き表示されます。
コンピューターの構成
コンピューターに ASP.NET と.NET Frameworkをインストールし、IIS をアンインストールして再インストールすると、スクリプト マップが壊れ、ASP.NET は機能しません。 この場合は、ASP.NET IIS 登録ツール (Aspnet_regiis.exe -i) を使用して、ASP.NET スクリプト マップを修復できます。
関連トピック