ページ

2009年7月31日金曜日

[Silverlight] Silverlight 3 でマルチタッチ

Silverlight 3 Multi-touch: The Basics より。
Silverlight 3 はマルチタッチに対応してます。
と言うか、Windows の WM_TOUCH メッセージに対応していると言った方がいいのかも。
ちなみに、リファレンスを見るとわかるとおり WM_TOUCH メッセージは Windows 7 と Windows Server 2008 R2 以降となっています。なので、Silverlight 3 だからと言って、XP や Vista でマルチタッチできるようになるわけではありません。
さらに Silverlight はブラウザの上で動くわけですからブラウザにも依存するのかもしれません。
MSDN Library の Multitouch Input には IE8 が必要そうなことが書いてあります。Windows 7 なので IE7 という選択肢はそもそも無いのかも知れませんが、Firefox とかがどうなるのかはよくわかりません。

Silverlight 上での実装方法ですが、単に System.Windows.Input.Touch クラスFrameReported イベント を受け取るようにするだけです。
FrameReported イベントに渡される TourchFrameEventArgs の GetTouchPoints() メソッドなどでタッチされている座標などがわかりますので、あとは好きなように実装すれば OK です。

Silverlight 3 Multi-touch: The Basics にはデモ動画やサンプルコードもありますので、興味のある人は見てみては。


[Silverlight] 同じページ上に Silverlight 2 と 3 が両方ある場合の話

Silverlight Version Compatibility より。
ある一つのページ上に Silverlight 2 アプリと 3 アプリの両方が混在して存在した場合どうなるか、という話です。

Silverlight 3 プラグインがインストールされていれば、Silverlight 2 アプリも 3 アプリも Silverlight 3 プラグインの上で動くことになります。
そして、2 アプリは v2 “quirks mode” な AppDomain で、3 アプリは v3 “quirks mode” な AppDomain で動きます。

quirks mode について、Silverlight のプログラムマネージャである Tim Heuer 氏のブログに簡単にですが書いてありました。
Check your Silverlight 2 apps for compatibility with Silverlight 3 の “A word on quirks mode” のところ。
要するに Silverlight 3 の中には Silverlight 2 互換モードがあって、AppManifest.xml の RuntimeVersion が 2.0.31005.0 (Silverlight 2 のときのバージョンナンバー) であれば自動的にこの Silverlight 2 互換モードで動くようになっているということみたいです。

これら 2つの記事の内容をあわせると、Silverlight アプリごとに AppDomain が作られ、また、quirks mode は AppDomain ごととなっている、ということになりますから、一つのページに 2 アプリと 3 アプリが混在していても問題は発生しないようになっている、ということになるわけですね。


2009年7月30日木曜日

[XNA] DeskTopLive.xna

http://b-o-w.jp/events/dtl_xna/
なにこれ、行きてぇ!

上記のサイトは少々見にくい(笑)ので、もう少し見易いのを XNA Today さんより。
DeskTopLive.xna の開催内容が発表されました


[Office] PowerPoint で HLSL

HLSL in Office より。
PowerPoint のアドインを書いてみたそうです。
そのアドインとは、画像と HLSL のソースを読み込んで、その画像にエフェクトをかけてくれるというもの。
記事で紹介されているソースコードを見ると、HLSL ソースコードをファイルとして保存して、それを DirectX SDK に含まれている fxc.exe でコンパイルして、できたファイルのパスを WPF の PixelShader に渡してエフェクトをかけて、なんてことをしています。
あとは、PngBitmapEncoder で PNG ファイルにして、VSTO でごにょごにょして PowerPoint に画像を挿入しているようです。

まぁ、実用というより実験的なものなんだと思いますが (fxc.exe が必要なので DirectX SDK を入れとかなくちゃいけませんし) こんなとこにも HLSL が出てくるのかぁ、と思ったもので紹介してみましたw


2009年7月29日水曜日

[.NET] IDisposable をスレッドセーフに実装する

A simple and totally thread-safe implementation of IDisposable より。
IDisposable をスレッドセーフにするリファレンス実装。
Interlocked.CompareExchange を使って軽量にスレッドセーフにしてますが、やってることはごく普通にスレッドセーフにしているだけですね。普通に lock なんかを使っても意味は同じです。

正直、IDisposable をスレッドセーフにする必要を感じたことは無いんですが、何となく気になったので。

ちなみに、IDisposable の実装方法のガイドラインは↓にあります。
アンマネージ リソースをクリーンアップするための Finalize および Dispose の実装
ここにあるように Dispose() メソッドは何回呼ばれても大丈夫なようにしておかなくちゃいけません。
ただ、スレッドセーフにしろとはまでは言ってませんし、実際、Dispose() メソッドがスレッドセーフになっているクラスはほとんどないんじゃないかと思います。


[Silverlight] Silverlight 3 には ItemContainerGenerator があるのか

Silverlight 2 には ItemContainerGenerator が無いため自前で実装する方法を 「[Silverlight] ListBox や ComboBox の各行の見た目にアクセスする」 で紹介しましたが、
ItemContainerGenerator in Silverlight 3
によると Silverlight 3 には標準で ItemContainerGenerator があるんですね。
まったく知らなかった。

ちなみに、Silverlight 3 版の Silverlight Toolkit も独自に ItemContainerGenerator を実装するのはやめてビルトイン版のものを使うように変更されているそうです。(自分では確認してませんが)


2009年7月27日月曜日

[Silverlight] Silverlight 3 で表示している内容を印刷する

"Printing" in Silverlight 3 with WriteableBitmap より
これはすごいな。

Silverlight で表示している内容のスナップショットを印刷する方法が紹介されています。
ブラウザの印刷機能を使えば Silverlight で表示している内容も含めて印刷してくれると思いますが、ここで紹介されているのはまったく別の方法です。

まず、WriteableBitmap クラスを使って Canvas をビットマップ化します。
(WriteableBitmap には UIElement を渡せるので Canvas でなくても何でもいいです)

続いて Joe Stegman 氏の PNG encoder の EditableImage クラスを使って上記のビットマップを PNG にして、そのバイト配列を Base64 化した文字列として取り出します。

この Base64 化した PNG 文字列を、あらかじめ HTML 上に用意してある <input type=”hidden”> な項目の value としてセットしてやり、サブミット (PostBack) してやります。

あとは、これをサーバで受け取って、PNG を組み込んだ PDF を作るなりなんなりしてレスポンスを返してやれば OK です。

なるほどなぁ。
実にすばらしい。


2009年7月14日火曜日

[Office] Office 2010 には無料の Web ブラウザ版もあるらしい

7/13 の Worldwide Partner Conference 2009 で Microsoft Office 2010 のテクニカルプレビューの発表があったそうで、情報がいろいろと出てきてますね。
その中に、無料の Web ブラウザ版の話もあります。
Excel、Word、PowerPoint、OneNote が IE や Firefox で動くというものです。
さすがにクライアントアプリ版と同じってわけではなく、それなりに低機能版らしいですが。

http://www.microsoft.com/office/2010/
の “Office Web Applications” のところにビデオがありますが、ちょこっと IE や Firefox で動いているところが見れます。
リボンなんかもあるようで、それなりに Office っぽいですね。
けど、これ、何で作ってあるんだろう?
Silverlight だったりしたらそれはそれでおもしろいような気がするんだけど。
と思ったら、Twitter で 「Office 2010 web apps - perhaps one of the most ambitious script# projects!」 なんてつぶやきが。
Script# ってことは Ajax なアプリなのか。


2009年7月13日月曜日

[Expression] Expression Encoder 3 ではスクリーンキャプチャができるようになるらしい

Windows Media エンコーダ 9 にはスクリーンキャプチャ機能があったのに、Expression Encoder には無くなっちゃってたんですよね。
それが 「What’s new in Expression Encoder 3」 によると、Expression Encoder 3 にはスクリーンキャプチャ機能が付くようです。
良く読んでないけど、他にも H.264 のサポートの向上とかいろいろと良くなってるみたい。


[Silverlight] Silverlight 3 正式リリース

アナウンス通り 7月 10日に Silverlight 3 が正式リリースされましたね。
まぁ、もう、いろいろなところで紹介されてるので今さら書くことは無いんですが(笑)

Silverlight 3 Released! What is new/changed?
こちらに beta 1 から変わったところが紹介されてたので、気になったところだけピックアップ。

  • テキストのレンダリングが進化したらしい。ここには書かれてないけど、他のブログで ClearType をサポートするようになったので文字がきれいになったし、小さい文字も読みやすくなったと書かれてるのを見た。
  • 今まで Silverlight Tools を入れると勝手に入ってた ASP.NET サーバコントロールの asp:Silverlight と asp:Media は無くなった。<object> を書けばいい。欲しけりゃ http://silverlight.net/learn/whitepapers.aspx にある。
  • アセンブリキャッシングは beta では Microsoft の特定のアセンブリのみキャッシュ可だったが、どのアセンブリをキャッシュするか自由に指定できるようになった。
  • DataForm は Silverlight Toolkit に移動した。
  • (記事には書かれてないけど) Blend SDK ってのもあるみたい。Blend 3 に一緒に入ってる or 別途ダウンロードも可。Behaivor とかを作るときに必要なものが入っている模様。

[MS] Office 2010 THE MOVIE

http://www.office2010themovie.com/

なんだこれwww
さすが Microsoft が本気出すと凄いなwww


2009年7月8日水曜日

[.NET][COM] 続:Marshal.ReleaseComObject の危険性について

[.NET][COM] Marshal.ReleaseComObject の危険性について」 の記事へのコメントで Jitta さんに 「More on ReleaseComObject (and why we did not implement IDisposable on the classes contained in the RCW)」 という続き的な記事があることを教えてもらいました。
せっかくなのでこちらも軽く紹介。

以下、「More on ReleaseComObject (and why we did not implement IDisposable on the classes contained in the RCW)」 より。

[厳密な訳ではありません。かなり大雑把ですし、一部英文の意味がよくわからないところもあります。正確なところはぜひ原文をご覧ください。なお、文字色や区切り線は原文にあわせてあります]


RCW に IDisposable を実装しなかったのは RCW が積極的に COM オブジェクトを Release することにリスクがあるからだ。それらのリスクの詳細は Yves blog link を参照して欲しい。


けど、それから誰かに聞かれた。


OK。RCW が IDisposable を使わないと決めたことに異議は無い。必要無いときに ReleaseComObject を呼ぶべきではないということにも同意する。

しかし、他の 2つの点について同意できないことがある。

RCW への参照を保持しているコードを ReleaseComObject したあとに使うことができないということ。

あるスレッドが ReleaseComObject を呼ぶときに他のスレッドが同じオブジェクトを使っていると、AV [アクセス違反のこと] が発生したりメモリがおかしくなったりすること。

#1 (前者のこと) は COM オブジェクトに限ったことではない。アンマネージリソースをカプセル化しているオブジェクトには同じことが言えるはず。たとえば、FileStream オブジェクトはクローズしたあとにリードやライトをすることはできない。しかし、FileStream は IDisposable を実装できないということはない。

#2 (後者) は私には理解できない。ReleaseComObject は IUnknown::Release を一度呼び出すんだよね?そうであれば、他のスレッドにどう影響するんだ?COM インターフェースをスレッド間でマーシャリングするとき CoMarshalInterThreadInterfaceInStream を呼びそれから CoGetInterfraceAndReleaseStream を呼ぶ。この結果オブジェクトの参照カウンタは一つインクリメントされる。オブジェクトがフリースレッドモデルで同じマルチスレッドアパートメントに属す 2つのスレッド間でマーシャリングするときは、確かに物理的に同じポインタを受け取ることにはなるが、その場合であっても参照カウンタはインクリメントされる。あるスレッドが ReleaseComObject を呼び、別のスレッドがそのオブジェクトを使っていたとしよう。ReleaseComObject の結果として参照カウンタは 1つデクリメントされるけれども、オブジェクトはまだ生きてるし、2番目のスレッドは普通に動く。なぜ AV やメモリがおかしくなると言ったことになるのか理解できない。


Dave の追加説明。


#1 について。他のマネージドコンポーネントも同じじゃないかということは正しい。しかし、RCW 自身が持っている COM コンポーネントを呼び出すたびに切断されていないかどうかをチェックするというコストを払いたくない。そのようにスタブは最適化されている。RCW はこの最適化された x86 スタブを通じてメソッドを呼び出すので、すでに ReleaseComObject を呼ばれている場合には AV の原因となり得る。こういったわけで、IDisposable を実装してるほとんどのマネージドコンポーネントの振る舞いよりもひどいことになってしまう。

#2 について。両スレッドが MTA ならばプロキシを取得する必要はないし、パフォーマンス的な理由で呼び出しのたびに COM コンポーネントの AddRef や Release を呼び出したりしない。この理由で、MTA スレッドから ReleaseComObject を呼び出すと別の MTA スレッドでメソッドを呼び出したときに COM コンポーネント内部で AV が発生したりプロセス全体の状態がおかしくなったりする。

結局のところ以下のような話なのかと思いました。

#1 の方を前回の記事と合わせて考えると、要するに 「ReleaseComObject でも IDisposable でもいいけど、もうちょっとうまいことできないのか?」 という話に対して 「COM の呼び出し部分ってなかなかそううまくいかない。だから IDisposable はやめた。ReleaseComObject は用意しておくけど不用意に使うと死ぬよ。だからコード書く人が十分に気を付けて ReleaseComObject を使うか、もしくは反対に何もせずにランタイムに任すかして欲しい。ランタイムに任せたときは GC によって解放された時かプロセスが終了するときに Release されることになるよ」

#2 の方はそれなりに COM のことがわかってないと意味わからないかもしれませんね。
COM の仕様上、呼び出し元も呼び出し先も MTA (と言うか、フリースレッドと言った方がいいのかな?) ならばマーシャリングする必要はありません。同じポインタを使い回して問題ありません。これがプロキシを取得する必要が無い理由です。
MTA の場合はスレッドをまたいでも同じポインタを使い回しているということなわけですから、結局のところスレッドまたぎかそうでないかはまったく関係ない話になって、#1 と同じ話ということになるわけです。

じゃ、MTA じゃない場合は?
この場合にスレッドを超えようと思うと COM インターフェースポインタのマーシャリングが必要になるし、スレッド間の通信は実はメッセージポンプがベースだったりとか COM の一番ややこしい世界に入っていきます。
なので、RCW がどうやって管理してるのかなんて私にはさっぱりわかりませんw
と言うか、あらためて考えてみたら、たとえば STA な COM インターフェースポインタを持っている RCW があったとして、その RCW がマネージドな世界で別のスレッドに渡された場合っていったいどのタイミングで CoMarshalInterThreadInterfaceInStream、CoGetInterfaceAndReleaseStream してるんだろう?
あれ?
RCW が自動的にこれらをやってくれるってことは無いのかな?普通の方法ではどうやっても無理なような気がする。。。
ひょっとして、Marshal.GetComInterfaceForObject なりでインターフェースポインタを取り出して自分で CoMarshalInterThreadInterfaceInStream、CoGetInterfaceAndReleaseStream してやらないといけないのかな?

7/8 19:50 追記
さっそく渋木さん、菊池さんからコメントとトラックバックを頂きました。(ありがとうございます)
MTA じゃない場合、というか、COM インターフェースポインタのマーシャリングについてはやはり RCW は一切何もしてくれないそうです。
両スレッドが MTA だった場合は COM の仕様的にマーシャリングが必要無いわけですから、結局のところ 「RCW はスレッドのことなんてまったく何も気にしていない」 ということになるかと思います。
なるほど、だから #2 の方は両スレッドが MTA の場合についてのみ論じれば十分なわけですね。
それ以外の場合はそもそも COM の仕様的に不正な呼び出しになってしまうため、ReleaseComObject がどうこうという以前の問題になってしまうわけです。


2009年7月7日火曜日

[Silverlight][Expression] Silverlight 3 と Expression 3 は 7月 10日ローンチ

News: Microsoft Silverlight 3 and Expression 3 Launch より。
Silverlight 3 と Expression 3 が 7月 10日(たぶん米時間) にローンチされるようです。
なんか、virtual launch event とか書いてあるから、どこかでイベントがあるんじゃなく、ネット上でイベントがあるってことなのかな?
http://www.seethelight.com/
ここでキーノートセッションや in-depth セッションなんかが見れるみたいです。
(今アクセスすると残り日数がカウントダウンされてます)

結局、beta 1 の後は何も出ずに RTW か。
ほんとに大丈夫なんだろうか?


[Silverlight] マイケル・ジャクソン告別式を Smooth Streaming で配信

July 7th, 10AM PT/1PM ET、ロサンゼルスのステイプルズ・センター (the Staples Center in Los Angeles) で開催されるマイケル・ジャクソンの一般向け告別式が Smooth Streaming + Silverlight を使って HD 品質で中継されるそうです。
http://inmusic.ca/news_and_features/Michael_Jackson

(日本時間だと 8日の AM2時になるのかな?間違ってるかも)

2ch でもやけに評判がよかったスムースストリーミングですがw (【1080p】MS Silverlightのスムースストリーミングが凄すぎる件【XBOXLIVE】) さすがに今回は相当なアクセスがあるでしょうし、サーバや回線が耐えられるのかちょっと心配。
逆に言うと、HD 品質は無理にしてもそれなりに配信できたらあらためて 「スムースストリーミングすげぇ!」 ってことになるかも。


[Silverlight] windows4all.com

http://windows4all.com/
すごっ
Silverlight で作った Vista 風のデスクトップですね。
デスクトップと言っても、もちろん、ブラウザの中で動くわけですが。

ちょっと不思議に思った点。
デスクトップの中に Internet Explorer のアイコンがあって、これを立ち上げるとちゃんとブラウズできます。
しかし、Silverlight には WebBrowser コントロールみたいなものは無かったはずです。
これ、どうやってるのか不思議でした。
ちゃんとは調べてませんが、たぶん、HtmlPage 経由で HTMLDOM を操作して <frame> か何かを Silverlight の上に重ねてるんじゃないかと思います。
うまいこと考えたなぁ。
ちなみに、Firefox で http://windows4all.com/ にアクセスした場合も Internet Explorer がありますが、ブラウザ部分で右クリックしたときに出てくるコンテキストメニューは Firefox のものだったりします(笑)

ところで、こういうのを見ると http://www.windowsvista.si/ を思い出す人もいるんじゃないかと思います。
以前に自分の書いた 「www.windowsvista.si - WPF/E のサンプル」 なんて見ると、まだ Silverlight という名前が無く WPF/E と呼ばれていたころなんですね。


2009年7月2日木曜日

[.NET][COM] Marshal.ReleaseComObject の危険性について

先日書いた 「[IE][C#][COM] IE のセキュリティゾーンをプログラムから操作する」 に、元記事を書かれた Dennis "D.C." Dietrich さんがコメントをくれました。
(わざわざ翻訳して読んでくれたそうです。コメントをもらったのは 6/26 ですが、今まで書く暇がありませんでした)

そのコメントにて
Discussion of Marshal.ReleaseComObject and its dangers
こちらの記事を紹介してくれました。

[厳密な訳ではありません。かなり大雑把ですし、一部英文の意味がよくわからないところもあります。正確なところはぜひ原文をご覧ください]

Marshal.ReleaseComObject を使えば望んだときに即座にリリースできる。しかし、COM コンポーネントのマネージド表現である RCW のこれを呼ぶとき、もしこの RCW を AppDomain 上の他のマネージドコードが保持していると、リリースできなくて InvalidComObjectException が発生するだろう。

さらに悪いことは、呼び出しがすでにリリースされた RCW に行われると、その振る舞いは未定義である。AV [訳注: アクセスバイオレーションのこと?] が発生する機会になったり、メモリを腐らせたり、妙なクラッシュをするまでだらだらと実行し続けたりとデバッグをするのが非常に大変になったりする。

このリスクは CoCreateInstance が毎回同じインターフェースポインタを返すようなシングルトンな COM コンポーネントの場合にさらに悪化する。AppDomain 内の別々の独立したマネージドコードが同じシングルトンな COM コンポーネントの RCW を使っているとき、それらのうちのどれかがその COM コンポーネントの ReleaseComObject を呼び出すと他のところが壊れる。

これが、本当に必要だという場合を除いて ReleaseComObject を使うべきではないと私が強く勧める理由だ!

別の話として、本当に ReleaseComObject を使う必要があるときには、.NET Framework 2.0 からある Marshal.FinalReleaseComObject を使うべき。この API は RCW が何回参照されていても COM コンポーネントをリリースしてくれる。FinalReleaseComObject ならばループの中で ReleaseComObject がゼロを返すまで繰り返すなんてことをしなくて済む。

なるほど、ものすごく納得です。

IInternetSecuriryManager のような COM インターフェースの場合は、うかつに Marshal.ReleaseComObject を呼び出すくらいなら放置しておいた方が安全というですね。
ただ、リリースのタイミングで後始末するようなインターフェースもあったりするので、常に放置すればいいとは限りませんし、単純に 「○○すればいい」 というようなルール化は難しいでしょうからケースバイケースで判断するしかないでしょうね。

ちなみに、Excel を Automation 経由で呼び出す場合なんかの話は、上の議論とは別だと思います。
こういった場合は、Excel のプロセスをきちんと終了させるために、かなり気を使って Marshal.ReleaseComObject を適切に呼び出してやらなくちゃいけません。
ReleaseComObject を適切に呼び出すということは、言いかえれば生成からリリースまでそのすべてを自分で管理するということです。
ですから、上記で言っているような 「他のところでリリースしちゃった」 というようなことはおこり得ません。(と言うか、そういったことが無いように全部自分で管理するわけですが)