ページ

2011年12月26日月曜日

[Windows8] ピクチャパスワードの解説

ピクチャ パスワードを使ってサインインする」 より。

Windows 8 の新しいサインイン方式 「ピクチャパスワード」 (要するに、画像に 3回程度タッチしてそのパターンをパスワードにする) の安全性などについて解説されています。
タップと線と円を組み合わせれば 3回程度で結構な強度になるんですね。
「画面に残る操作痕に対するセキュリティ策」 なんてことも考えなくちゃいけないのはおもしろいな。これに関連してちょっと思ったのは、パスワードをキー入力しているところを盗み見てもとっさに全文字覚えるのは大変ですが、ピクチャパスワードなら覚えることができちゃいそうってところかな?

2011年12月22日木曜日

[WP7] Windows Phone 上でアプリ開発ができるツール - TouchDevelop

TouchDevelop v2.5: new tutorial, artwork, forum, and more より。

へえぇぇぇ、こんなのがあったんですね。
TouchDevelop という Windows Phone 7 アプリです。すでにバージョン 2.5 なので結構前からあったのかな?
サイトなどを見るとわかるように開発しているのは Microsoft Research です。Microsoft Research というのは Microsoft 社の研究開発部門なので、このアプリも研究の一環なんでしょう。

で、この TouchDevelop ですが、このアプリ自体がアプリの開発環境であり、実行環境にもなっています。
アプリの開発は、独自言語を持っていて、その言語でガシガシ書いていくようです。スクリーンショット に “action main()” で始まるいかにもプログラムっぽいものがありますが、コレです。
ただ、アルファベットをすべて打ち込むわけではなく、カーソルがあるところの文脈にあわせてそこで使えるコマンドなどが表示されるのでそれをタップして行くという感じです。(インテリボタンと言うみたい)
たとえば チュートリアル (英文・PDF) では、まず Shake イベントを選びます。続いてこのイベントの中身をプログラミングするんですが、「media ボタンをタップ」「songs ボタンをタップ」「rand ボタンをタップ」「play ボタンをタップ」 と 4回タップするだけで 「保存されている曲をランダムに再生」 というコードが出来上がる、なんて感じです。

もちろん、作ったアプリはいつでも実行できますし、Pin すればスタートスクリーンに配置することもできます。
また、Publish すれば公開することもできます。公開したアプリは誰でも TouchDevelop で読み込んで実行することができますし、コードを編集することもできるようです。また、公開されているアプリは https://www.touchdevelop.com/ でも見ることもできますし、こんな風に コードの内容も丸見え状態になってます。

TouchDevelop をインストールすると最初からいくつかサンプルが入っていて、実行したりコードを編集したりできます。これを書きながらちょこちょこと眺めてみましたが、なかなか興味深いです。

2011年12月21日水曜日

[WP7] PhoneGap が Windows Phone 7.5 に完全対応

PhoneGap が 1.3 で Windows Phone 7.5 に完全対応したそうです。
Full Support for PhoneGap on Windows Phone is Now Complete!

PhoneGap は HTML5+CSS3+JavaScript フレームワークで、これを使えば iOS や Android などのマルチプラットフォーム対応アプリケーションを作成することができます。(と言っても、私は使ったこと無いですし、ぜんぜんわかってないですが)
HTML5 と言っても Web サイト上のアプリではなく、出来上がるのはクライアントアプリです。
WP7 の場合は .xap ファイルが出来上がります。(.xap の中に HTML5、CSS3、JavaScript などのファイルも含まれています)
なので、普通のアプリと同様にマーケットプレース経由で配布することになります。

Get Started with PhoneGap on Windows Phone 7
こちらのブログには紹介動画もありました。
PhoneGap をインストールすると Visual Studio 2010 用のプロジェクトテンプレートも入るようです。これでプロジェクトを新規作成すると一通り必要なものは自動作成されます。あとは HTML なり CSS なり JavaScript なりをガシガシ書いていくだけです。

一本目の紹介動画を見ると、navigator.notification.alert(“メッセージ”); なんてやるとちゃんと WP7 風のメッセージボックスが表示されてます。(ソース見たわけじゃありませんが、HTML で擬似的に作ってるんじゃなく、WebBrowser コントロール経由で本物の MessageBox を呼び出してるんじゃないかと思います)
console.log(“ログ出力”); なんてやると Visual Studio の 「出力」 に出力されます。(これは System.Diagnostics.Debug.WriteLine を呼び出してるのかな)

二本目の動画では、カメラを呼び出してます。
カメラは navigator.camera.getPicture() で呼び出せるようですが、どうやらデフォルトではカメラはサポートされていない様子。
と言っても、サポートするのは簡単で、PhoneGap に Camera.cs というソースが含まれているのでそれをプロジェクトの Plugins フォルダに追加するだけ。サイズをコンパクトにできるようにプラグイン方式にしているんでしょうね。

2011年12月20日火曜日

[WP7] エミュレーターでもラジオのテストができる

Windows Phone Arch 主催の Windows Phone Hackathon in Osaka (12/4 開催) のときに 「FM ラジオってエミュレーターでは鳴らせませんよねぇ」 という話をしていたら 「いや、鳴らすことできますよ」 と教えてもらいました。

エミュレーターでも周波数 88.5 もしくは 89.5 にすれば音楽が流れるようになってるんですね。88.5 と 89.5 ではちゃんと違う曲が流れます。もちろん本物のラジオが鳴るわけではなく、エミュレーターに埋め込まれた音楽が鳴るだけですが。
コードで書くと

Microsoft.Devices.Radio.FMRadio.Instance.Frequency = 88.5;

これだけでエミュレーターから音楽が鳴り始めます。

しかし、この情報ってどこに書いてあるんだろ?MSDN Library を検索してみましたがどこに書いてあるのかわかりませんでした。

2011年12月19日月曜日

[Silverlight] Silverlight 5 の 3D アクセラレーションがデフォルトで動かない件

前の記事の 「[Silverlight] Silverlight 5 の 3D アクセラレーションはデフォルトでオフ(オフと言うか拒否)」 について。
正直、自分では 「ふーん、デフォルトでは拒否なんだ」 程度にしか思ってなかったんですが、これってかなり残念な感じかも、という気がしてきました。

Silverlight 5 で 3D なゲームを作っても一般の人にはよくわからない理由で動かないわけです。
動くようにするためには以下の手順で 「許可」 してもらう必要があるわけです。

  1. Silverlight プラグインの上で右クリックして 「Silverlight(S)」 をクリック。
  2. 表示されたダイアログの 「アクセス許可」 タブをクリック。
  3. 一欄から自分のサイトを探してもらう。(URL が列挙されてるだけなのでわかりやすいとは言えないかも。frame で別サイトを組み込んでいたりする場合はどうなるんだろう?)
  4. 見つかったらそいつを選んで 「許可」 ボタンを押してもらう。

単に 「アクセス許可を与えてくれ」 だけじゃ、それなりの人にしかわからないでしょうから、この手順を書いとかなくちゃダメって感じになりますね。
先の記事にも書いたように GraphicsDeviceManager.Current.RenderMode を見ればハードウェアアクセラレーションが使えるかどうかがわかるので、それで表示・非表示してやる感じでしょうか。メッセージボックスだと OK ボタンを押して閉じないと Silverlight プラグイン上で右クリックできないので、見ながら操作できるように XAML で書いといた方がよさそうですね。
アプリにもよるでしょうが、最低限、日本語と英語くらいは用意しておいた方がいいかもしれません。

でも、一番の問題はなぜデフォルトでは拒否されているのか、それを許可するとどうなるのか、をきちんと説明しないといけないことじゃないかと思うんですよ。
HTTPS なんかでもありますよね。オレオレ証明書を使っていて 「警告メッセージが表示されるけど問題ないからそのまま OK してくれ」 なんて説明してるサイトが。問題があるから (問題がある可能性があるから) 警告メッセージがでるわけで、こんないい加減な説明をしていいはずがありません。
これと同じで 「何も考えずに 3D グラフィックスを許可してくれ」 はまずいんじゃないかと思うわけですよ。
けど、きちんとした説明を書く自信なんて無いなぁ。

■ RequestDeviceAccess() は無いの?
Silverlight 4 からはカメラやマイクが使えるようになってますが、これも知らないうちにオンにされたりしたら困るわけで、ちゃんと使う前に許可を得なくちゃいけません。
そのために CaptureDeviceConfiguration.RequestDeviceAccess() という静的メソッドが用意されています。
このメソッドを呼び出すだけで

Silverlight5_CameraAccess.png

このダイアログが表示されます。
右クリックしてどうのこうのとしなくても、このダイアログで簡単にアクセス許可の可否を選択できます。
「回答を保存する」 をオンにすれば右クリックで出るダイアログの 「アクセス許可」 のところにちゃんと記録されます。
もちろん、今の言語にあわせて日本語なり、英語なりで表示されます。
「詳細情報」 のリンクをクリックすればマイクロソフトのプライバシーポリシーの説明が表示されます。

3D グラフィックスには RequestDeviceAccess() に相当するものって無いですよね?
デフォルトで拒否でいいからこれを用意して欲しいなぁ。

2011年12月16日金曜日

[VS11] Visual Studio 11 の Direct3D サポートすごいな

Somasegar’s Weblog 「Visual Studio 11 Platform Tooling Advances」 より

Visual Studio 11 の Direct3D 関連のサポートがすごいことになってるんですね。

■ The first area of improvement
HLSL (High-Level Shader Language。GPU に対する命令を記述するための C 言語風の言語) が VS で普通にサポートされるみたいです。
あまり詳しくないんですが、以前は DirectX SDK に付いてる外部の HLSL コンパイラ(fxc.exe)を呼び出してコンパイルしてたと思いますが、これは XNA GameStudio でも今だに変わってなかったのかな?それがきちんと VS に統合されるという感じでしょうか。
また、エディターもちゃんと色付けやインデントなど C# や VB と同じようにサポートされるようです。(当然インテリセンスもできるんでしょうね)

シェーダーではいろんなことができますが、ピクセルシェーダーでは
    「マテリアル表面のテクスチャ A」 と 「陰影のテクスチャ B」 を合成する
みたいなことをやったりします。
これをビジュアルに編集するノードエディターが搭載されるようです。編集中もリアルタイムに結果が表示されるとか、”Time” ノードでアニメーションも定義できるとか、なにこれ、すげぇ!
もちろん、ビジュアルに編集した結果は HLSL がジェネレートされます。

■ The second area of improvement
.FBX や .DDS のビューワーも搭載されるようです。これで 3D モデルを VS11 内で確認できるとのこと。
(さすがに 3D モデルの作成機能は無いよとのこと)

■ The third area of improvement
DirectX のフレームをキャプチャしたり、GPU パイプラインの内容を参照したり、ピクセルの描画イベントを参照したりといった GPU のデバッグ機能が搭載されるそうです。(このあたりは (これまた詳しくありませんが) DirectX SDK や XNA GameStudio にはあった機能かもしれませんが)

--

今まで DirectX 関連は DirectX SDK や XNA GameStudio にまかせっきりだったものが、Visual Studio 本体に機能追加されつつ統合されるという感じでしょうか?
Windows Phone はもともと XNA をサポートしてますし、Silverlight も 5 で XNA サポートと、本体と分離して考えるほうが無理が出てきたってことかもしれませんね。

2011年12月15日木曜日

[Silverlight] Silverlight 5 の 3D アクセラレーションはデフォルトでオフ(オフと言うか拒否)

Silverlight 5 では GPU アクセラレーションが強化されて 3D とかも速くなったとかなんとか。。。ということだったので、試してみようと
http://david.blob.core.windows.net/babylon/Babylon.html

にアクセスしてみました。ここは、Code Recipe でコードが公開されている Babylon 3D engine のデモサイトです。

が、サイトにアクセスすると以下のようなメッセージボックスが表示されて正常に実行されません。

Error during initialization:Hardware rendering is disabled by security reason. Please right click on your silverlight plugin, go to permissions tab and allow 3D for this application.

解決策はこのメッセージに書いてあるとおりなんですが、Silverlight 上で右クリックしてコンテキストメニューを表示、「アクセス許可」 で 「3D グラフィックス」 を 「許可」 してやります。それからページをリロードしてやれば今度はメッセージボックスが表示されること無く、実行されるはずです。

Silverlight5_Allow3D.png

明示的に許可してやらないとダメなんですね。
確か WebGL もセキュリティ的な問題があるというような記事を読んだような記憶があるんですが、これも同じような理由でしょうか?GPU のことも、セキュリティのこともあまり詳しくはありませんが、確か以下のような話だったような。。。

Silverlight はサンドボックス内で実行されているのでどうがんばってもマシンに悪影響を与えることはできません。Silverlight ランタイムがいろいろがんばってセキュリティ的な悪影響を与えないようにしてくれてるわけです。しかし、GPU やグラフィックスドライバといった 3D アクセラレーションの部分は Silverlight ランタイムの管理外になってしまいます。今どきの GPU はすごく高機能で、単に画像を表示するだけではなく、シェーダー言語と呼ばれる C 言語風の言語で処理内容を定義するようなことができます。このあたりを利用して物理演算なんかも GPU でやってしまおうという DirectCompute、OpenCL、CUDA なんてものもあります。確か Silverlight 5 はシェーダーモデル 2.0 のシェーダー言語をサポートしていたんじゃないかと思います。こういったシェーダー言語の部分も含めて Silverlight の管理外となってしまうわけです。もちろん、GPU が 「マネージド」 になってて Silverlight ランタイムと同様に安全性を検証できるようになっていれば問題ないんでしょうが、もともと 「いかに高速に処理するか」 をメインテーマに進化してきたものなのでセキュリティ的な面からはいろいろとまずい所があるんでしょう。
そんなわけで 3D アクセラレーションに関する部分については Silverlight ランタイム側で安全性を保証できない、だから明示的にユーザーが許可してね、ということなんじゃないかと思います。

ところで、Babylon のデモサイトですが、“Predefined scenes:” のところでシーンファイルを選んでやるとデモ用に用意されたシーンが描画されます。データを読み込むのには時間がかかりますが、読み込んでしまえば 60fps で動いてました。

また、この 「3D アクセラレーションが使用可能か?」 の判断方法については Bobylon 3D engine の作者さんのブログにも書いてありました。
Silverlight 5 is out!
GraphicsDeviceManager.Current.RenderMode を見ればハードウェアアクセラレーションが使えるかどうかがわかり、GraphicsDeviceManager.Current.RenderModeReason を見ればハードウェアアクセラレーションが使えない理由がわかるようです。

2011年12月14日水曜日

[Live] SkyDrive API

まだよく読んでませんがちょっと覚え書き。

SkyDrive APIs for Docs and Photos—now ready to cloud enable apps on Windows 8, Windows Phone and more

もともと含まれていたのか、それとも今回追加されたのかはよくわかりませんが、最近リリースされた Live SDK 5.0 には SkyDrive だとかカレンダーだとかにアクセスするクラスが含まれているようですね。それだけでなく、REST で SkyDrive にアクセスする方法なんかも公開されているみたい。

Windows Phone 用の公式 SkyDrive アプリもリリースされましたが、Live SDK を使えば SkyDrive 対応アプリを作るのも簡単そう。

# 実は一番驚いたのは Live SDK のサンプル を見ようと思ったらサンプルの公開に github が使われてることだったり。
# Microsoft 公式で、Download Center とか CodePlex とかでなく github が使われてるのなんて初めて見た。

2011年9月29日木曜日

[WP7.1] Windows Phone SDK 7.1 のリリースノートに書かれてることで気になったところ

Windows Phone SDK 7.1 の正式版がリリースされましたね。
とりあえず、リリースノート を見てみました。(RC のときはリリースノートは英語のままでしたが、今回はリリースノートも日本語に翻訳されてます)

で、気になったところ。

「その他」のところにちょこっと書かれてるんですが、

  • 「HttpWebRequest オブジェクトの Response.ContentLength プロパティは、65,536 バイトを超えるすべての応答に対して 0xFFFFFFFF を返します」
    ってなんかすごいなw ContentLength プロパティって long(Int64)なのに上限が 65,536って。まぁ、HTTP 的に ContentLength は必ずしもあてに出来るプロパティじゃないから別にいいってことだろうけど。
  • 「XmlnsDefinitionAttribute クラスの使用はサポートされていません。使用すると、アプリケーションが応答を停止する場合があります」
    例外が出るとかじゃなく、アプリがだんまりになっちゃうってこと?まぁ、XmlnsDefinitionAttribute って使ったこと無いけど。
  • 「複数行テキスト ボックスでは、改行文字に \r\n ではなく \r を使用します」
    これは RC にも記述がありましたが、\r\n に決め打ちしてると困ることがあるかも。
  • 「XNA Framework レンダリングを使用する ListBox コントロールは、正常にスクロールしません」
    これも RC にも書いてありました。「ScrollViewer.ManipulationMode="Control"」 をつければ OK と。
  • 「Bing、Marketplace 検索、WebBrowser タスク プロパティで、Unicode 文字が正しく機能しない。 この問題を回避するため、タスクは Unicode 文字を使わずに表記してください」
    まじですか?!
    var searchTask = new MarketplaceSearchTask();
    searchTask.SearchQuery = "日本語";
    searchTask.Show();
    RC のエミュレーターでこうやるとバケバケになります。HttpUtility.UrlEncode("日本語") としてもダメです。これがそのまま正式版になっちゃったってこと?(誤訳かもと思って 英語のリリースノート を見てみましたがまったく同じことが書かれてました)
    ”Bing” っていうのは BingMapsTask の SearchTerm のこと?最近せっかく日本の地図がまともになったのに、BingMapTask で日本語検索できないとしたらがっかりだなぁ。
    WebBrowserTask ってのはどういうことだろ?
    var bworserTask = new WebBrowserTask();
    bworserTask.Uri = new Uri("http://www.bing.com/search?q=" + HttpUtility.UrlEncode("日本語"));
    bworserTask.Show();
    

    ってのが動かないってことは無いよね?(RC ではちゃんと動く。てか、UrlEncode してるんだから Ascii 文字しか使ってないし)WebBrowserTask には他に文字列使うプロパティは無いと思うんだけど?(URL プロパティは Obsolete になってる)

続く 「互換性に影響する変更点」 には結構いろいろ書かれてます。こちらは「理由」や「対処方法」も書かれてますし、一度は読んどいた方がいいかも。

あと、「元に戻された互換性に影響する変更点」 の 「既定では、画像のデコードは UI スレッドではなくバックグラウンド スレッドで発生します」 というのがすごくわかりにくい。RC のリリースノートには 「バックグラウンドスレッドでするようにしたけど、リリース版では元に戻す」 と書いてあったので、7.0 ではデフォルトで UI スレッド → 7.1 ベータではデフォルトでバックグラウンドスレッド → 7.1 正式版ではデフォルトで UI スレッドに戻った、ということなんだと思います。で、バックグラウンドスレッドでやりたいときは自分で BackgroundCreation と指定すればいいということなんじゃないかと。

2011年9月28日水曜日

[WP7] @IT:たった30分で完成。初めてのWindows Phone 7.5アプリ開発

@IT に記事が掲載されました。
たった30分で完成。初めてのWindows Phone 7.5アプリ開発

「WPFやSilverlightでの開発経験がある方に向けて、Windows Phoneでのアプリケーション開発がどのようなものかを紹介」という内容です。よろしければぜひご一読ください。

2011年9月9日金曜日

[WP7] Silverlight for Windows Phone Toolkit August 2011 のサンプルをビルドする

デブサミ関西のセッションでも 「Silverlight for Windows Phone Toolkit はとっても便利」 という話をしたんですが、サンプルを見てみようとするとうまく動かなかったりするので、書いときます。(将来のリリースでは修正されるといいなぁ)

まずは Silverlight for Windows Phone Toolkit August 2011 のソース & サンプルをダウンロード。
http://silverlight.codeplex.com/releases/view/71550
ここの 「Silverlight for Windows Phone Toolkit Source & Sample - Aug 2011.zip」 ってやつです。

ダウンロードして Windows Phone SDK 7.1 が入った環境で PhoneToolkit.sln を読み込んでビルドすれば OK、、、だといいんですが、エラーや警告がでます。

まず、「Xap パッケージ化に失敗しました。オブジェクト参照がオブジェクト インスタンスに設定されていません。」 というエラーが発生する件。
これは、PhoneToolkitSample プロジェクトの Image フォルダにある画像ファイルのファイル名が文字化けしているのが原因です。
私の環境だと København.jpg と Mürren.jpg が文字化けしてました。
ファイル名をリネームしてやるなりして、ちゃんと参照できるようにしてあげてください。

それから、「Silverlight for Windows Phone Toolkit - Aug 2011.msi」 の方でセットアップした Microsoft.Phone.Controls.Toolkit.dll には PhoneTextBox が入っていないようです。なのでこの dll を参照した状態では PhoneToolkitSample をビルドすることはできません。
もし PhoneTextBox 関連のエラーが出るようなら PhoneToolkitSample の 参照設定でいったん Microsoft.Phone.Controls.Toolkit への参照を削除し、参照の追加で 「Microsoft.Phone.Control.Toolkit プロジェクト」 への参照を追加しなおしてください。dll への参照ではなくて、プロジェクトへの参照です。「Silverlight for Windows Phone Toolkit Source & Sample - Aug 2011.zip」 に入っているソースコード版の Toolkit には PhoneTextBox がちゃんとあるのでこれでビルドできるようになります。

あと、「プロジェクト 'Microsoft.Phone.Controls.Toolkit' を参照できません。参照されるプロジェクトは、異なるフレームワーク ファミリー (Silverlight) を対象としています。」 という警告が出ます。これを消すには Microsoft.Phone.Controls.Toolkit.Design プロジェクトと Microsoft.Phone.Controls.Toolkit.VisualStudio.Design プロジェクトの参照設定にある Microsoft.Phone.Controls.Toolkit への参照を一度削除し、Microsoft.Phone.Controls.Toolkit プロジェクトをビルドした結果できあがる Microsoft.Phone.Controls.Toolkit.dll (Bin フォルダの下にあります)への参照を追加してやれば OK です。(こっちはプロジェクトの参照ではダメで、dll への参照にしてやる必要があります)

これでサンプルを動かすことが出来るんじゃないかと思います。
(他にも警告が出ていますが、それらは無視しても大丈夫そう)

[イベント] デブサミ関西に行ってきた

2011/9/7 神戸で開催された Developers Summit 2011 Kanai に行ってきました。
今回は 「【B-5】 ついに日本上陸! Windows Phone 7.5 アプリケーション開発」 というタイトルでセッションを担当させて頂きました。
もちろん、スピーカーとしてだけでなく、他のセッションも全部聞くつもりです。。。

。。。と、思ってたんですよ。
しかし、最近仕事がいろいろと忙しく、結局この日も担当セッションのちょっと前に到着、到着後もスピーカー控え室でお仕事の続き、となってしまいまったく他のセッションを受講することはできませんでした。とっても残念。

さて、自分のセッションについて。
内容自体は 2011/6/19 の VSUG DAY 2011 Summer のときのセッション 「はじめてのWindows Phone 7 アプリケーション開発」 のアップデート版です。VSUG DAY のときは 「Mango ではこうなる予定」 という状況でしたが、その後 8/18 に Windows Phone SDK 7.1 RC 日本語版 がリリースされ、8/25 には世界初の(そして、現時点では世界唯一の) Windows Phone 7.5 搭載機 IS12T が AU からリリースされ、という状況を受けてのアップデートです。セッション資料も VSUG DAY のときに作ったものを細々とアップデートして使いました。(使い回しともいいますが(笑))
こういう風に同じような内容のセッションを 2回やるというのは今回が初めてでした。やっぱり 2回目になるとかなり余裕を持ってお話できますね。まぁ、自分に余裕があると感じただけで、聞かれている方がわかりやすかったのかどうかは何とも言えませんが(汗)
そうそう、会場に行って初めて知ったんですが、手元を映すカメラが用意されてました。これで WP7.5 の実機を映しながらデモを行うことができました。ただ、こういう機材があるって知らなかったので、あんまり活用できてなかったですね。すっかり頭の中ではエミュレーターだけでデモをするつもりで段取り作っちゃってましたから。今にして思うとせっかく実機を映せるんだからもっと使えばよかったなぁ。
Twitter でもつぶやきましたが、「【A-5】 関西ITコミュニティ集まれ!デブサミ名物コミュニティLT大会」 と被ってたので、ほとんどの人はそっちに行くかなぁと思ってたんですが、想像以上にたくさんの方に来て頂けました。もちろん、LT 大会はもっとたくさんの人だったんでしょうけどw
セッションに参加してくださった皆さん、ありがとうございました。ちょっとでも参考になれば幸いです。

今回のデブサミ関西のセッション資料は以下にアップロードされています。私のもしておきました。
http://www.slideshare.net/event/developers-summit-2011-kansai

終了後は懇親会。
大いに盛り上がりました。
二次会にも参加して夜遅くに帰宅。

他の方のセッションにまったく参加できなかったのは残念でしたが、それでもとても楽しい一日でした。
スピーカーの皆さん、スタップの皆さん、参加された皆さん、お疲れ様でした。そして、ありがとうございました。

2011年6月30日木曜日

[WP7.1] Beta2 のリリースノートに書かれてることで気になったところ

今朝から Windows Phone SDK 7.1 Beta2 がダウンロードできるようになったようで一部で盛り上がってますが、とりあえず Release Notes を見てみました。
しっかり読んだわけじゃありませんが、ちょっと気になったところを覚え書き。

Known Issues のところ

  • Controls のところ、「マルチラインの TextBox は “\r\n” の代わりに改行として “\r” を使う」
  • Silverlight and XNA Framework のところ、「XNA Framework レンダリングしている ListBox は正しくスクロールしない。ScrollViewer.ManipulationMode=”Control” を付けると解決する」

これらってそのうち直るってことなんだろうか?それともこのまま?

Breaking Changes のところ

  • 最初にある 「ScrollViewer と ListBox の入力処理が UI スレッドじゃなくなった」 というのは 「[WP7] Mango で ListBox や ScrollViewer のパフォーマンスが向上する」 ここで書いたやつですね。
  • 次に 「画像のデコードは UI スレッドではなく、バックグラウンドスレッドで実行される」 なんてあります。ちょっとでも UI スレッドを軽くしようということですね。けど、「Caution: This change will be reverted in a future release. 」 なんて注意書きが。しかも、「You should not make any changes to your application code.」 なんてことまで。(この変更は将来のリリースで元に戻される。なので、あなたのコードを書き換えたりしないこと)良かれと思ってやってみたけど、イマイチだったから元に戻すってことなのかな?
  • その次には 「非同期 web client リクエストのレスポンスはバックグラウンドスレッドで動く」 なんてあります。今までこのあたりは非同期ではあるけど UI スレッドも使っている (詳しく調べてませんが、確か UI スレッドをブロックしてると WebClient からのレスポンスも返ってこなくなってたような) という感じでしたが、完全に別スレッドで動くようになるってことでしょうか?

[WP7] WebBrowser コントロール (WP7.0)

Windows Phone 7 の WebBrowser コントロールについてのもろもろ
注意: 以下は 7.1(Mango)ではなくすべて 7.0 の情報です。7.1 では IE9 ベースに変わってるので WebBrowser コントロールもいろいろと変わってるんじゃないかと思います。それらについてはまだまったく調べてません。

■ NavigateToString() メソッドで日本語表示
NavigateToString() メソッドで日本語を表示しようとすると化けます。内部では utf-8 に変換していないのに utf-8 で渡しちゃってるとかそんな感じなのかな?
とりあえず 「International UTF-8 Characters in Windows Phone 7 WebBrowser Control」 にあるように文字実体参照にして渡せば化けずに表示できます。

■ Data URI scheme は未サポート
Data URI scheme っていうやつ (HTML の中に <img src=="data:image/png;base64,ここにBASE64の文字列”> なんて書くやり方)について。
仕様については↓にあります。
data Protocol (MSDN Library)
The "data" URL scheme (RFC2397)
残念ながら NavigateToString() メソッドでこの書式の HTML を書きこんでも画像は表示されません。(×印になってしまう)
検索してみたら、このやり方ができるようになったのは IE8 からだそうです。で、WP7 の IE は 7+ くらいだからそもそもサポートしてないんじゃね?ということらしいです。
ということは、WP7.1(Mango) ではできるようになってるかも(未確認)

■ WebBrowser コントロールのリファレンス
WP7 の WebBrowser コントロールのドキュメントは↓
WebBrowser Control for Windows Phone
けど、ほとんど何も書いてないな。

■ WebBrowser コントロールから HTML 内の JavaScript を呼び出す
WebBrowser.InvokeScript() メソッドで HTML 内の JavaScript メソッドを呼び出すことができます。
(ただし、事前に IsScriptEnabled = true にしておく必要あり)
たとえば、HTML 内に func() という名前の関数があった場合には

this.webBrowser1.InvokeScript("func”);

といった感じです。
関数に引数がある場合は this.webBrowser1.InvokeScript("func”, “abc”, “あいう”); でいけました。(この場合、日本語も化けませんでした)

■ HTML 内の JavaScript からの呼び出しを WebBrowser コントロールのイベントで受け取る
WebBrowser.ScriptNotiry イベントで HTML 内の JavaScript から呼び出しをイベントとして受け取ることができます。
HTML 内に <input type="button" onclick="window.external.Notify('button1 click')" value="click"/> なんてのがあった場合、

this.webBrowser1.ScriptNotify += webBrowser1_ScriptNotify;

private void webBrowser1_ScriptNotify(object sender, NotifyEventArgs e)
{
    MessageBox.Show(e.Value);
}

という感じです。

■ 拡大縮小できないようにする
Web ブラウザーなので拡大縮小できてしまいますが、これは <head> に

<meta name="viewport" content="width=200"/>
<meta name="viewport" content="user-scalable=no"/> 

を入れておくと禁止できるようです。

2011年6月27日月曜日

[Silverlight] Silverlight を囲む会 in 大阪 #19 に参加しました

Silverlight を囲む会 in 大阪 #19 に参加してきました。
今回のメインテーマは SharePoint。
SharePoint MVP でもあり、SharePoint をメインに扱う会社の代表取締役でもある山崎さんをスピーカーに迎えて。
私自身は SharePoint のことはほとんど初心者レベルだったので、初めて知るようなことが多く、いろいろとおもしろかったです。
Silverlight Web パーツの開発のお仕事なんてできるとおもしろそう(残念ながら今のところ SharePoint を使っているという人(個人・法人)の心当たりがまったくありませんが)

また、30分ほどのショートセッションでしたが、マイクロソフトのエバンジェリストである大西さんの Windows Phone 7 Mango の紹介。
休憩時間中に実機もさわらせてもらいました。
あぁ、Mango が楽しみ。

伊勢シンさんの 「Socketプログラム Siverlight for Windows Phoneへの移植のポイント」 もおもしろかった。
伊勢シンさんは 「誰得だよ」 とおっしゃってましたが、私にとっては結構 「俺得」 でしたw

最後にいろいろなプレゼントの抽選会。
先週の VSUG DAY 2011 Summver 東京 の際にマイクロソフトの高橋忍さんから 「大阪で勉強会があったときにでも配ってください」 と Windows Phone 開発技術情報 DVD と WP-Arch シールを頂いていたのでそれも希望者に配布しました。DVD は 20枚くらいあったので余ると思ってたんですが、品切れになっちゃいました。ということは、ほぼ全員が持って帰ったってことですね。やっぱり、直前に大西さんに Mango 実機を見せてもらってるし、みんな興味を持ったのかもしれませんね。

その後はお楽しみの懇親会。
その後、大西さんを交えての二次会、さらに三次会と楽しい一日でした。

2011年6月17日金曜日

[VSUG] VSUG DAY 2011 Summer

2011/06/19 に品川にて開催される VSUG DAY 2011 Summer に参加します。

http://vsug.jp/tabid/228/EventID/17/Default.aspx

VSUG DAY 2011 Summer

「はじめてのWindows Phone 7 アプリケーション開発」 と題したセッションを担当させて頂きます。
(けど、マイクロソフトの高橋さんのセッションもあるので、WP7 について聞きたい人は高橋さんに聞くといいと思うよw)

2011年6月16日木曜日

[WP7] Mango で ListBox や ScrollViewer のパフォーマンスが向上する

Listbox – ScrollViewer performance improvement for Mango and how it impacts your existing application?
こちらの記事より。

「Outlook とかの標準アプリ(Windows Phone 7 に標準で入っているアプリ) のぬるぬるさに比べると、俺らのアプリいまいちなんだけど」 という声がそれなりにあったということでしょうか?ListBox のぬるぬるさが足りないというフィードバックが結構あったようで Mango では入力関係の入力スレッド、アニメーション関係のコンポジタースレッド、アイテム生成の UI スレッドに分けて処理することによって ListBox や ScrollViewer のパフォーマンスが向上するそうです。

ただ、そのために若干動作が異なる部分が出てくるみたい

  • ScrollViewer でスクロールしているときのプロパティの更新(UI スレッド上)
    • WP7 上の 7.0 アプリ
      プロパティが変化するとすぐさま更新
    • Mango 上(7.0 アプリと 7.1 アプリの両方)
       a. 指を離したとき
       b. 任意の方向にスクリーンの 1/4 以上ドラッグ、パン、フリックしたとき
      にプロパティが更新される
  • ScrollViewer の中でドラッグして Manipulation Delta イベントが発生するのは (UI スレッド上)
    • WP7 上の 7.0 アプリ
      ScrollViewer の中にあるエレメントによってハンドルされるこれが可能
    • Mango 上(7.0 アプリと 7.1 アプリの両方)
      入力スレッド上のイベントなので ScrollViewer によって飲み込まれる。スクロールしているときに不必要なイベントを発生しないようにするというパフォーマンス向上の一環

この非互換性が困ると言う場合は、どうやら

<ListBox ItemsSource="{Binding Items}" ScrollViewer.ManipulationMode ="Control" Height="652" Canvas.Top="80">

と言う風に ScrollViewer.ManipulationMode ="Control" を付けることができるようです。
ただし、これはまったくお勧めしない方法ということみたい。

もうちょっとましな方法は、ScrollViewer の中に横スクロールする TextBlock を組み込むとかそういう風にコードを書き換えることだそうです。
ちょっと詳しいことは読み取れてませんが、きっと縦スクロールは ScrollViewer のまかせてぬるぬるに、横スクロールはパノラマみたいにちょっとしか必要ないことが多いだろうからそっちは TextBlock とかを使って従来のスクロールにする、というような意味じゃないかと思います。横方向にたくさんのスクロールが必要な UI っていうのは普通は無いでしょうからね。

で、最後に、当然ながら ScrollViewer や ListBox を使ってない場合はなにも変わらないとあります。
たとえば、Silverlight for Windows Phone 7 Toolkit に入っている LongListSelector とかは効果なしだそうです。
えっ?と思って LongListSelector の XAML を見てみたら、これって Canvas に自前で描画してるみたいですね。誰か ScrollViewer を使う形に書きなおしてくれないかなぁ。

[.NET] スレッドセーフな ObservableCollection<T> が欲しい

Windows Phone 7 のコードを書いていると今まで以上に UI スレッドをブロックしたくなくなるんですよね。(ぬるぬるにしたいからw)

で、今更ながらに ObservableCollection<T> についてどうにかならないか考えてたんですが、どうにもなりそうにないですねぇ。
ObservableCollection<T> は INotifyCollectionChanged を実装してコレクションに変更があったことを通知してくれるようになってるわけですが、この INotifyCollectionChanged の CollectionChanged イベントは 「何番目の要素が変更されたか」 といった情報も伝えるようになってます (NotifyCollectionChangedEventArgs 参照)。で、CollectionChanged イベントを受け取るのは ListBox などの UI 要素であることが多いわけです。必ずしもそうと決まっているわけではないですが、ObservableCollection<T> を使うのは ListBox などの ItemsSource にしたいから、という場合がほとんどじゃないかと思います。そして、ListBox などの UI 要素のほとんどの機能は UI スレッド以外から呼び出すことはできません。呼び出すと例外が発生します。そのため、CollectionChanged イベントも UI スレッド以外で発生させるのは危険ということになります。
ObservableCollection<T> に対して Insert や Remove などを行うと自動的に CollectionChanged イベントが発生するわけですから、結局のところ UI スレッド以外でこういったコレクションの内容を変更することはできないわけです。もちろん、Insert や Remove の処理自体は別スレッドで行って、CollectionChanged イベントの発行のみ UI スレッドでやるという実装も可能ですが、CollectionChanged イベントの呼び出しが終わるまでコレクションの内容が NotifyCollectionChangedEventArgs の内容と整合性が取れていることを保証しなくちゃいけませんから、結局のところあんまり別スレッドで Insert、Remove などの処理を行う意味は無いって感じになってしまいます。

ObservableCollection<T> 単体で考えればスレッドセーフにする意味があるかもしれませんが、ListBox の ItemsSource にデータバインディングしている ObservableCollection<T> と考えると ListBox の中身まで含めて都合をつけなくちゃいけないのでどうにも手の出しようがないって感じですね。
こういう風に考えると、この記事のタイトルは 「スレッドセーフな ObservableCollection<T> が欲しい」 ではなくて、「UI 要素に任意のスレッドからアクセスできるようにして欲しい」 というところに行き着いちゃうわけです。

「ObservableCollection threadsafe」 で検索するとすぐに Thread safe observable collection この記事が見つかりました。
見てみると、これもやはりほとんどのメソッドを Dispatcher 経由で UI スレッドにスイッチしてますね。参照系は ReaderWriterLock で別スレッドからでもアクセス可にしてあるので、その部分はパフォーマンス向上に繋がるかもしれませんが、それくらいかなぁ?
あと、この例では Dispatcher.Invoke() メソッドを使って UI スレッドに同期的にスイッチしていますが、Silverlight/WP7 には Invoke() は無いんですよねぇ。(BeginInvoke() しかありません)
Dispatcher.BeginInvoke() を使って非同期的に UI スレッドにスイッチするとなると、上にも書いたように UI スレッド側での CollectionChanged イベントの呼び出しが終わるまでコレクションの内容を維持してやるとかいった仕組みが必要になります。(CollectionChanged イベントの呼び出しが終わるまで次の Insert や Remove の実行をブロックするとか) そういう実装もやれないことは無いですが、あんまりパフォーマンスは良くならないような感じがしちゃいます。

と、言うわけで、この件は考えるのやめましたw
何かいいアイデアがあったら教えてください。

2011年6月15日水曜日

[WP7] プログラミング生放送勉強会 第9回@大阪に参加しました!

6/11 開催の プログラミング生放送勉強会 第9回@大阪 に参加させて頂きました。
どのセッションもとてもおもしろかったです。

そして、私も 「Windows Phone 7 用の 2ch ブラウザーを C# で作ってみた」 と題したセッションを担当させて頂きました。
「作ってみた」 と言うより 「作ってみてる」 ところなんですが。しかも、最近時間が取れずほとんど進んでないです。
一応、セッション資料をあげておきます。ただ、これだけ見てもあまり意味ないかもしれません。
ニコニコ動画のコミュニティ プログラミング生放送 で、今ならまだ生放送がタイムシフトで見られるようです。(見れるのは生放送から 1週間だったかな?いずれにしろ予約してない場合はプレミアム会員じゃないとダメなまずですが)
また、それとは別にプログラミング生放送の 5zj さんが動画を上げてくれました。sm14747480 こちらはいつでも見れるはず。


 

勉強会のあとは懇親会に参加。
最近、寝不足気味だったこともありかなりのテンションだったような気もしますが、ほんとに楽しかったです。
(次の日は二日酔いでヘロヘロでしたが)

2011年6月9日木曜日

[Silverlight] Silverlight 4 の ScrollViewer がマウスホイールでスクロールしない!(バグってる?)

確か記憶では、、、

Silverlight 2 のころはそもそもマウスホイールはサポートされてなかったので HtmlPage のホイールイベントをひろってどうのこうのと。。。

そして、Silverlight 3 では Silverlight Toolkit に ScrollViewer のマウスホイール対応クラスが入ってて scrollViewer.SetIsMouseWheelScrollingEnabled(true) って呼び出せばいいだけになってくれて。。。(ちなみに、SetIsMouseWheelScrollingEnabled は ScrollViewer の拡張メソッドとして実装されてるとのでこういうことができる)

それから、Silverlight 4 で標準でサポートされて、ScrollViewer は何もしなくてもマウスホイールでスクロール可能になった!

、、、ような気がするんだけど、Silverlight 4 でマウスホイールに反応しない。
検索してみたら Connect にこんなのあった
Mouse wheel does not work correctly with the Silverlight 4 ScrollViewer
うーむ、ブラウザーのせいなのか何のせいなのかわかんないけど、どうやらダメなときはダメみたい。
で、「回避策」 にあるように

<ScrollViewer Background="Transparent" ... > 

としてやれば OK だった。
うーむ。

Background を透明にしたくないってときは以下のような感じでいけるみたい。

private void LayoutRoot_MouseWheel(object sender, MouseWheelEventArgs e)
{
    var point = e.GetPosition(this.scrollViewer1);
    if (point.X < 0 || this.scrollViewer1.ActualWidth <= point.X || point.Y < 0 || this.scrollViewer1.ActualHeight <= point.Y)
    {
        // マウスが ScrollViewer の上で無い
        return;
    }

    if (!e.Handled)
    {
        double position = CoerceVerticalOffset(this.scrollViewer1, this.scrollViewer1.VerticalOffset - e.Delta);
        this.scrollViewer1.ScrollToVerticalOffset(position);
        e.Handled = true;
    }
}

private double CoerceVerticalOffset(ScrollViewer viewer, double offset)
{
    return Math.Max(Math.Min(offset, viewer.ExtentHeight), 0.0);
}

どういうわけかわかんないけど、Background が Transparent で無いときはなぜか ScrollViewer に MouseWheel イベントがこず、背面の LayoutRoot の方にいっちゃうみたい。なので、LayoutRoot の方で MouseWheel を受けて ScrollViewer をスクロールさせてやる、と。
ちなみに、スクロール部分のコードは Silverlight Toolkit の SetIsMouseWheelScrollingEnabled のあたりでやってることそのまんまです。

[WP7] 起動ページを MainPage.xaml 以外にする

Visual Studio のテンプレートで Windows Phone 7 のプロジェクトを作ると、起動ページとして MainPage.xaml が指定されています。
これを他の xaml に変更するには、Properties フォルダの下の WMAppManifest.xml にある

<Tasks>
    <DefaultTask  Name ="_default" NavigationPage="MainPage.xaml"/>
</Tasks>

ここを書き換えれば OK です。

まぁ、それなりに WP7 開発をやってる人にとっては常識なのかもしれませんが、私はちょっと悩んじゃいましたw
始めは、「App.xaml か App.xaml.cs あたりに書いてあるんだろう」 と思って見てみてもそれらしいものは無し。「じゃあ、プロジェクトの設定なのか?」 とプロジェクトのプロパティや、.csproj ファイルを直接テキストエディターで見てもそれらしいものは無し。結局、grep して見つけました。

2011年6月8日水曜日

[WP7] ListBox のデータの仮想化

Windows Phone 7 の ListBox はデフォルトでも VirtualizingStackPanel を使います。そのおかげで、見えている部分+α 程度の要素だけを生成します。
要するに、1万行ある ListBox でも最初にいきなり 1万行作るわけではなく、見えている部分の 10行ちょっと程度だけ作ることによって高速化してくれるわけです。
ただこれはビジュアル要素(TextBlock やら Border やらのこと)についてです。
データについては、1万行だったらあらかじめ 1万行分必要です。
それを、最初に 1万行分作らなくても済むようにしようというのが「データの仮想化」です。

Virtualizing Data in Windows Phone 7 Silverlight Applications
この記事によると IEnumerable では無く IList を継承したクラスを ItemsSource にセットすることで、必要になったデータのみを取得するようになってくれるようです。
ちなみに、必要なのは Count、IndexOf、this[] の get のみでそれ以外は NotImplementedException を投げるようにしとくだけでも構わないようです。

で、さっそく試してみみても常に全件取得されちゃってなぜかまったく仮想化されず悩みました。
ふと気付いて試してみてわかりましたが、ItemTemplate が無いと仮想化されないんですね。

<ListBox>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

このようにほとんど意味が無くても ItemTemplate は必須みたいです。

これで試してみると、最初にだいたい 100件程度分 this[] が呼び出されて、あとは ListBox をスクロールすると必要に応じて適当に this[] が呼び出されるという感じです。
もちろん、IList ではなく IList<T> を継承したクラスでも問題無く仮想化されました。

というか、IList と IEnumerable の両方を継承している場合はちゃんと仮想化されるようです(IList の方が優先されてる)。
なので、List<T>、ObservableCollection<T>、普通の配列など、いずれも大丈夫なんじゃないかと。
ダメなのは IEnumerable、もしくは、IEnumerable<T> しか無い場合です。
この場合は、GetEnumerator() が呼び出されて最初に全件取得されます。

というわけで、普通にコレクションクラスを使ってる時は自然とデータの仮想化も使ってることになりそうです。
IEnumerable しか無いっていうと、一番ありそうなのは LINQ 関連のことをやってる場合ですね。

public IEnumerable<Data> GetItemsSource()
{
    for (var i = 0; i < 10000; ++i)
    {
        yield return new Data(i);    // ←このデータを作るのが重い処理
    }
}

こんなメソッドがあって、これを ListBox.ItemsSource に渡してるとか、
もっと直接的に

this.ListBox.ItemsSource = from i in Enumerable.Range(0, 10000)
                           select new Data(i);    // ←このデータを作るのが重い処理

こんな風なことをしてると、1万個の Data クラスのインスタンスが出来上がるまで UI が固まってしまいます。(Data クラスの中身が string がいくつかあるだけとかなら、1万個くらい一瞬で出来上がっちゃうかな。そういう場合はほとんど気にする必要は無いと思いますが)
LINQ を使ってると、便利なんでついつい 「from なんちゃら~」 で済ませてしまおうとしちゃいがちなのでちょっと気をつけた方がいいかも。(と、自分に対して言っておくw)

2011年6月6日月曜日

[Silverlight][WP7] DependencyProperty.RegisterReadOnly が無い

すごく今さらですが、Silverlight・Windows Phone 7 には DependencyProperty.RegisterReadOnly() メソッドが無いんですね。
うーむ。
探してみたら
Sometimes you just gotta do the best you can [Tip: Read-only custom DependencyProperties don't exist in Silverlight, but can be closely approximated]
こんな記事はありましたが。。。
SetValue されたときに元の値に戻して例外を発生させるという力業。。。つか、ちっとも ReadOnly じゃないじゃん。
RegisterReadOnly() メソッドくらい用意しておいてくれてもよかったような。

2011年5月30日月曜日

[WP7] ScrollViewer のスクロールに反応する

Windows Phone 7 の ScrollViewer (確認してませんが、Silverlight や WPF でも同じかも) にはスクロールしたことを伝えるイベントがありません。
けど、スクロール量を表す HorizontalOffset、VerticalOffset プロパテイがあります。
ならば、これらにデータバインディングしてやればスクロールしたときにあわせて処理をできるんじゃないかと。

public static readonly DependencyProperty MyVerticalOffsetProperty =
    DependencyProperty.Register("MyVerticalOffset", typeof(double), typeof(MyView), new PropertyMetadata(0.0, MyVerticalOffset_PropertyChanged));

private static void MyVerticalOffset_PropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    // ScrollViewer.VerticalOffset が変わったときにここが呼ばれる
}

こんなのを用意しておいて、あとは

XAML で書くなら
<ScrollViewer VerticalOffset="{Binding MyVerticalOffset, Mode=TwoWay}" />

コードで書くなら
var binding = new Binding("MyVerticalOffset") { Source = this, Mode = BindingMode.TwoWay };
this.ScrollViewer.SetBinding(ScrollViewer.VerticalOffsetProperty, binding);

こんな感じでいいのかなぁ?と。

がっ!これはできないんですね。
ScrollViewer.VerticalOffset プロパティなんかは readonly なので、実行時に例外が発生してしまいます。
BindingMode.OneWayToSource にしてやればよさそうにも思えますが、Silverlight には OneWayToSource がありません。
というわけで、どうもこのアプローチはダメみたいです。

しかし、添付プロパテイであれば相手が readonly でも添付できるようです。

private static int verticalOffsetAttachedPropertyCounter = 0;

// コンストラクタ
public MyView()
{
    InitializeComponent();

    // ScrollViewer.VerticalOffset に添付プロパティをアタッチして変化を検出する
    var property = DependencyProperty.RegisterAttached("MyVerticalOffset" + verticalOffsetAttachedPropertyCounter, typeof(double), typeof(MyView), new PropertyMetadata(0.0, MyVerticalOffset_PropertyChanged));
    ++verticalOffsetAttachedPropertyCounter;
    var binding = new Binding("VerticalOffset") { Source = this.ScrollViewer };
    this.ScrollViewer.SetBinding(property, binding);
}

private void MyVerticalOffset_PropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    // ScrollViewer.VerticalOffset が変わったときにここが呼ばれる
}

こんな感じでうまくいきました。
上記ではインスタンス上で RegisterAttached してますが、もちろん、普段の依存関係プロパティのように static に RegisterAtached しても構いません。
その場合、当然 MyVerticalOffset_PropertyChanged() メソッドも static にすることになります。
今回、static ではなくインスタンスでやっているのは MyVerticalOffset_PropertyChanged() メソッドに渡される DependencyObject が添付先(今回の場合だと ScrollViewer)になっちゃうからです。依存関係プロパティのときはここに自分が渡されるのでキャストすれば自分のインスタンス変数にアクセスできますが、添付プロパティだと自分にアクセスするすべがなくなっちゃいます。そんなわけで static ではなくインスタンスにしています。

ただ、これ、インスタンスが作られるたびに RegisterAttached してるわけですが、いいのかな?まぁ、UnregisterAttached みたいな解除するための API が無いのでどうしようも無いんですが。

2011年5月28日土曜日

[Silverlight] 明日(いや、もう今日か)、「Silverlight を囲む会 in 大阪 #18」 に参加してきます

明日(いや、もう今日か)、 Silverlight を囲む会 in 大阪#18 に参加してきます。
テーマは LightSwitch だそうです。
Visual Studio 風のデザイナーで、Access みたいにちょこちょこと作れちゃう、しかも作ったものは Silverlight アプリに自動生成されちゃう、という 「ちょっとしたビジネスアプリはこれで作ればあっという間にできちゃうんじゃね?」 というものらしいです。いや、私自身はまったく触ってないので、間違ってるかもしれませんが(笑)

余裕のある会場みたいなので当日受付も OK みたいですよ。
(行ってみようという方は上記ページにある主催者連絡先メールなり Twitter なりでコンタクトを取ってみてください)

2011年5月27日金曜日

[Silverlight] OOB のブラウザーコントロールでローカルファイルをブラウズできない?

Silverlight のブラウザー外実行 (Out Of Browser) では WebBrowser コントロールが使えますが、これってどうやらローカルにあるファイルは表示できないんですね。

Silverlight 自身は OOB のときは分離ストレージ (IsolatedStorage)、「昇格された信頼」 な OOB のときはそれに加えて MyDocuments、MyMusic、MyPictures、MyVideos フォルダーにアクセスできます。なので WebBrowser コントロールも少なくともそれらの場所にあるファイルにはアクセス出来るもんだと思ってました。
しかし、”file:///c:/.../index.htm” とか “c:\...\index.htm” とかいろいろ試してみましたがどうやってもアクセスできません。

うーむ、これってできないんですかねぇ?

検索してみると、ファイルを String に読み込んで WebBrowser.NavigateToString() で表示することなら出来る、という記事はみつかるんですが、やっぱりみんな普通には表示できてないみたいな感じ。
完全にオフラインで動かすために、最初に HTML やらなんやらの必要なものをローカルにコピーしておいて以後はそれを参照する、ってな需要ってあると思うんだけどなぁ。(というか、それをやろうとして出来ないことに気付いたんだけど)

Silverlight 5 で何か変わってるんだろうか?(まだ 5 のノーチェック)

2011年5月25日水曜日

[WP7] ListBox の SelectionChanged イベントって、、、選択項目が変わらないと発生しないのね。いや、そりゃそうなのはわかるけど

Windows Phone 7 で ListBox で項目を選択すると、それに対応するページに遷移する。こういう動きってよくありますよね?
で、戻るボタンで戻ってくる。
そして、同じ項目をクリックする。。。と、うんともすんとも言いません。ListBox の SelectionChanged イベントが発生して欲しいんですが発生しません。

なぜ?と思いつつ検索してみるとすぐ見つかりました。
Reselect same item in listbox - did not fire "SelectionChanged" event
Microsoft の Peter Torr さんから 「選択項目が変わってないんだから SelectionChanged イベントは発生しないよ」
えぇぇぇぇぇ。いや、そりゃ確かにそうなんですが。。。
で、「SelectionChanged イベントが来たときに SelectedIndex に –1 を入れれば次もイベントが発生するよ」

なるほどぉ

私はこれで解決できました。
スレでは 「-1 入れるとハイライト表示が消えちゃう。選択されていることを示すハイライトを出したいときはどうすりゃいい?」 と言う感じでもうちょい続いてます。これといった結論は無いような感じですが。
まじめにやるなら、ListBox の DataTemplete に Button を仕込めばいいんじゃないかな?試してないからうまくいくかわからんけど。
ちょっと強引な方法としては、SelectedIndex = –1 にしたあと、Dispatcher.BeginInvoke で元の SelectedIndex に戻しちゃうとか?(この場合、たぶん SelectionChanged イベントが来ちゃうからそれは無視するとか結構強引な感じになると思うけど)

スレの最後に 「ListBox にも Click イベントがあればいいんじゃね?」 とかあるけど、確かにそうだな。

[WP7] LongListSelector でちょっとはまった

Silverlight for Windows Phone Toolkit に入っている LongListSelector はお手軽にグループ化したリストが作れて便利ですが、ちょっとはまったので記録として。

もっとも単純な形だと、

public class Book
{
    public string Category { get; set; }
    public string Name { get; set; }
}

こんなクラスがあったとすると、

var books = new Book[] {
    new Book() { Category = "Cat1", Name = "Book1" },
    new Book() { Category = "Cat1", Name = "Book2" },
    new Book() { Category = "Cat2", Name = "Book3" },
};

this.LongListSelector1.ItemsSource = from book in books
                                     group book by book.Category into c
                                     select c;

こんな風にすればグループ化して表示できます。

と思ってたんですが、これじゃダメなんですね。これだとグループヘッダーのところに何も表示されません。
この場合、ItemsSource には System.Linq.IGouping<TKey, TElement> のコレクションを渡していて、Key がグループヘッダー、グループの中身は GetEnumerator() で取得することになります。実際に group by で返ってくるのは IGrouping を実装した System.Linq.Lookup.Grouping クラス(リファレンスには載ってない)なんですが、どうやらこれの Key プロパティとうまくデータバインドできない様子。

Toolkit のサンプルを見ると

public class PublicGrouping<TKey, TElement> : IGrouping<TKey, TElement>
{
    private readonly IGrouping<TKey, TElement> _internalGrouping;

    public PublicGrouping(IGrouping<TKey, TElement> internalGrouping)
    {
        _internalGrouping = internalGrouping;
    }

    public override bool Equals(object obj)
    {
        PublicGrouping<TKey, TElement> that = obj as PublicGrouping<TKey, TElement>;

        return (that != null) && (this.Key.Equals(that.Key));
    }

    public override int GetHashCode()
    {
        return Key.GetHashCode();
    }

    #region IGrouping<TKey,TElement> Members

    public TKey Key
    {
        get { return _internalGrouping.Key; }
    }

    #endregion

    #region IEnumerable<TElement> Members

    public IEnumerator<TElement> GetEnumerator()
    {
        return _internalGrouping.GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _internalGrouping.GetEnumerator();
    }

    #endregion
}

こんなクラスを自前で用意して

this.LongListSelector1.ItemsSource = from book in books
                                     group book by book.Category into c
                                     select new PublicGrouping<string, Book>(c);

と言う風に包んであげています。
なぜそんな事に?

var q = from book in books
        group book by book.Category into c
        select c;
var group = q.First();
var key = group.Key;                                    // ちゃんと Key の内容を取り出せる
var propertyInfo = group.GetType().GetProperty("Key");    // null が返る!

こんな風に試してみました。
System.Linq.Lookup.Grouping クラスは DependectyObject ではありませんから、LongListSelector は内部でリフレクションを使ってデータバインドしてると思います。なので、GetProperty(“Key”) で PropertyInfo が取れないとバインドしようが無いと思いますが、実際に試してみると null が返ってきちゃいます。どうやら Grouping クラスは internal なのでリフレクションでアクセスできない様子。
ちなみに、まったく同じコードを .NET Framework 4 のコンソールアプリケーションと Silverlight 4 で試すとまったく問題なく PropertyInfo が取得できます。Silverlight と WP7 は null になるのかと思ったら、WP7 だけが動作が違うんですね。

分かってしまえばどうということは無いんですけど、ちょっとはまりました。
(というか、最初から public に Grouping クラスを用意しておいてくれたらよかったのに)

2011年5月24日火曜日

[WP7] App Hub のアカウントを作ってみた

HTC 7 Trophy を入手したので App Hub アカウントを作ってみました。
(会社の法人アカウントを作ってみようかと思ってたんですが、とりあえず個人にしました)

最近、公式で手順書が公開されたそうですが、私は今のところ特に問題なく進めることができました。

公式の手順書はこちら
App Hub のアカウント作成手順と注意事項

一部、手順書とは違う(メールが日本語だったり)ところもあるので私の場合を書いておきます。

  1. App Hub でアカウントを作成。私は以前から使っていた Live ID で登録。聞いたところによると、Live ID 作成時の国が「日本」になってないとダメとか、誕生日が 18才以上でないとダメとか、注意点があるそうです(あとから変更してもダメで作成時の情報がチェックされるらしい?)。Live ID 作成時のことなんて覚えてませんでしたが、私の場合は特に問題なく作成できました。
  2. ちょっとしたら App Hub から確認のメールが来ました。これはリンクをクリックしてメールアドレスの確認をするだけ。
  3. それから 1日半後くらいの土曜日の早朝に GeoTrust より「Windows Marketplace for Mobile ID XXXXXX」のメールが到着。私のところには日本語のメールが来ました。身分証明書確認のシートもちゃんと日本語です。

    確認シートの部分をプリントアウト
    ・身分証明書には運転免許証のコピーを使用
    ・「ID 番号」欄には運転免許証の番号を記入。
    ・「有効期限」欄には運転免許証の期限を「201X年X月X日」形式で記入。(文面が日本語になってるんだから日本語表記にしてみた)
    ・「発行場所」欄には「日本」と記入。
    ・「署名」欄には氏名、「日付」欄には当日の日付を「2011年X月X日」形式で記入。
    (以上手書き)

    これをスキャンしてメールに添付して送信。送ったのは GeoTrust からメールが来てから数時間後の土曜日の昼くらいです。
  4. 月曜日の昼に GeoTrust より認証手続き完了のメールが来ました。これもちゃんと日本語です。(締めの言葉は Thank you でしたがw)
  5. その翌日、Microsoft から「Windows Marketplace account notification」のメールが来て無事 App Hub アカウントが作れたようです。

結局、6日間でアカウントの作成はできました。途中に土日を挟まなければもっと早くできるのかもしれませんね。

さっそく、HTC 7 Trophy を繋いで Windows Phone Developer Registration を起動。
App Hub アカウントで Register すると無事登録されました。
Visual Studio から実機に繋いでのデバッグも問題なし!

ところで、今のところ有料アプリを作る予定はないんだけど、EIN の取得と W-8BEN の申請はしておいたほうがいいのかな?

2011年2月14日月曜日

[Silverlight] Silverlight を囲む会 in 大阪 #16 に参加してきた

この間も書いたように Silverlight を囲む会 in 大阪 #16 に参加してきました。
Windows Phone 7 がテーマということで、とてもおもしろかったです。
プログラミング生放送の 5zj さんがニコ生でも生放送してくれていました。2011/02/18(金) 23:59:59 までタイムシフトで見ることができます。(タイムシフトはプレミアム会員じゃないとダメなのかな?)
しょっぱなの私のセッションは Visual Studio とエミュレーターのみですが、他の皆さんのセッションは Windows Phone 7 実機を使ってのセッションです。ぬるぬると気持ちよく動くさまが見れます。

もちろん懇親会にも参加。あー楽しかった。

2011年2月7日月曜日

[Silverlight] Silverlight を囲む会 in 大阪 #16

Silverlightを囲む会 in大阪 #16 に参加します。
今回のテーマは 「Windows Phone 7 のための Silverlight 開発講座」 です。
入門のセッションのスピーカーを担当させてもらいます。
Visual Studio と Windows Phone エミュレーターでどんな感じで開発ができるのかといった、入門的なところを主にして話させてもらうつもりです。

まだ、申し込み受付中のようですので興味のある方はぜひ。

2011年2月5日土曜日

[ブログ] FC2 から Blogspot へデータを移行したときの覚え書き

FC2 にあった記事をここ Blogspot へ移行したときの覚え書きです。

■ FC2 → Blogger
まずは、FC2 ブログの管理ページにある「エクスポート」で記事データをエクスポートします。
このデータはどうやら MT 形式みたいです。MT 形式であれば http://movabletype2blogger.appspot.com/ で Blogger 形式に変換できます。
FC2 からエクスポートしたデータは euc-jp になってるので utf-8 にしてやります。
続いて http://movabletype2blogger.appspot.com/ で Blogger 形式に変換、と思ったらちょっと問題が。

  • 日時がすべて変換した時のものになってしまう。
    これは movabletype2blogger が “02/12/2008 09:03:25 PM” という AM/PM 付きの形式を前提としているのに対して FC2 のデータは “02/12/2008 21:03:25” と AM/PM が無いためです。ちなみに、MT 形式のドキュメントを見ると AM/PM を省略したときは 24時間表記とあったので movabletype2blogger の実装が手抜きなんでしょう。本当ならは movabletype2blogger の方を修正するのが筋ですが、手っ取り早く DATE: のところを AM/PM 形式に変換するプログラムを C# でちょこっと作って対応しました。
  • タイトルがおかしくなったり、コメントにゴミが入る。
    これは MT 形式ファイルのコメントのところにある TITLE、SECRET、PASS のせいで、Blogger 形式にしたときにタイトルがコメントのものに置き換わってしまったり、コメントの中に SECRET や PASS の文字列がそのまま残ってしまったりします。MT 形式の仕様上これらがどういうものなのかは調べてませんが、消してしまえばいいようだったので手作業で削除しました。
  • 記事やコメントの日時がずれる。
    FC2 からエクスポートしたデータは JST なのに GMT として扱われるためです。これは Blogger 形式にしたあとで、<ns0:published> と <ns0:updated> の Z を +09:00 に置換して JST にしてやりました。

これで Blogspot にインポートすることができました。

[ブログ] .Text から Blogspot へデータを移行したときの覚え書き

.Text にあった記事をここ Blogspot へ移行したときの覚え書きです。

■ .Text → BlogML
まずは http://www.divakk.co.jp/blog/aoyagi/ で動いていた .Text (dotText : ASP.NET C# で書かれたブログエンジン。.NET Framework 1.1 のころのもの) を BlogML 形式に変換。
BlogML というのはブログデータの形式のことです (ファイル自体は XML)。
.Text、Community Server、Subtext、BlogEngine.NET、DasBlog といった .NET 系のブログエンジンでサポートされていることが多いみたいです。(私は今回初めて知ったので詳しいことはわかりません)

変換には http://www.johnsample.com/ のツールを使わせてもらいました。ソースも載っていますしバイナリもダウンロードできます。このソースでは BlogML 名前空間のクラスを使っていますが、それは http://blogml.codeplex.com/ にあります。

■ BlogML → WXR
続いて BlogML 形式を WXR 形式にします。
WXR 形式は Wordpress が使っている形式です。
BlogML から WXR への変換は Importing BlogML into WordPress こちらにある XSLT を使わせていただきました。

まず、XSLT に合わせて BlogML の最初の方にある xmlns=”http://www.blogml.com/2006/09/BlogML” を消します。
次に、もとの .Text の日付が JST を前提にしてあるため XSLT の <xsl:template name=”topubdate”> のところの +0000 を +0900 にして JST に合わせます。
あとは BlogML のファイルにこの XSLT を適用してやるだけ。

私は、BlogML の 2行目に <?xml-stylesheet href="BlogML2WXR.xsl" type="text/xsl"?> と書いて IE で読み込みました。
もちろん、単に IE で読み込むと XSLT を適用した結果を HTML として解釈したものが表示されるだけです。
XSLT を適用した結果の XML を取り出すのに、私は
Internet Explorer Tools for Validating XML and Viewing XSLT Output
を使ってます。
こいつを実行して解凍すると msxmlvw.htm と msxmlvw.inf が入ってますので、これらを適当なフォルダに入れておいて msxmlvw.inf を右クリックして「インストール」
これで IE を立ち上げなおして BlogML を読み込んだ状態で右クリックすると 「View XSL Output」 が増えてます。
これで XSLT を適用した結果の XML を表示させることができますので、コピー&ペーストして utf-8 で保存してやれば OK です。

こうして作った WXR 形式のファイルを wordpress.com のブログにインポートしてみたら一応きちんとインポートできてました。(ただし試したのは記事 1つ分だけ)

■ WXR → Blogger
WXR 形式を Blogger 形式にします。
wordpress2blogger というツールが http://code.google.com/p/google-blog-converters-appengine/ にあります。このツールは Python で書かれてるみたいです。このツールが http://wordpress2blogger.appspot.com/ で動いてますので、私はこれを使わせてもらいました。(ただし、一度に変換できるのは 1M バイトまで)

ただ、上記の手順で作った WXR を変換しようとしたらエラーになりました。
pubDate が fmt=%a, %d %b %Y %H:%M:%S になっていないと言われます。
とりあえずエラーが出ないように XSLT の <xsl:template name=”topubdate”> のところの <xsl:param name="date" /> の後ろに “Mon, “ と書き足して変換しなおしました。
これだとすべての日付が Mon (月曜日) になってしまいますが、きっと曜日なんて読み飛ばしてるだけでしょうから問題ないでしょう。

■ Blogger 形式のデータを Blogspot にインポート
これで .Text のデータが Blogger 形式になったので Blogspot の設定ページにある 「ブログをインポート」 でインポートします。
ただ、以下の修正が必要でした。

  • ”<ns0:link href=”001” ... ”  のようになっているところがあるので “<ns0:link href="http://www.blogger.com/" ... “ に変更。(いつの間にか href の値がおかしくなっていた。これがおかしいとインポート時にエラーが出て読み込めない)
  • “<ns0:published>2003-07-05T18:18:00Z</ns0:published>” を “<ns0:published>2003-07-05T18:18:00+09:00</ns0:published>” に変更。(JST なのに “Z” となっているためインポートすると時間がずれる。なので “+09:00” としてやる)

これで無事 Blogspot にインポートできました。