Home |  バックナンバー |  ソースコード |  ニュース |  MSDN Magazine別冊 |
 MSDN Magazine 日本語版     

マイクロソフトテクノロジー エンサイクロペディア DVD-ROM版
  Back Issues Index
 2000
 2001
 2002
 2003
Source Code Index
MSDN Magazine 別冊
MSDN magazine US site
Microsoft.NETシリーズ 第4弾!
C#で始めるプログラミング「導入編」
C#で始めるプログラミング「導入編」
2002年10月18日発売!

Sample Code
 
C#で始めるプログラミング「オブジェクト指向編」
C#で始めるプログラミング「オブジェクト指向編」
2002年10月18日発売!

Sample Code
 
Microsoft.NETシリーズ 第3弾!
Microsoft.NET実践プログラミング - Best of MSDN Magazine 2001 -
Microsoft.NET実践プログラミング - Best of MSDN Magazine 2001 -
2002年7月2日発売!

Amazon.co.jpから御購入いただけます
 
Microsoft.NETシリーズ 第2弾!
Visual Basic.NETオブジェクト指向プログラミング入門
Visual Basic.NETオブジェクト指向プログラミング入門
2002年6月13日発売!

Amazon.co.jpから御購入いただけます
 
Microsoft.NETシリーズ 第1弾!
ASP.NETプログラマためのXMLテクニック
ASP.NETプログラマためのXMLテクニック
2002年3月1日発売!

Amazon.co.jpから御購入いただけます
 
msdn
April 2003 No.36 (2003年3月25日発売)
特集1 Visual Studio .NET 2003の最新プログラム環境
Windowsフォーム:名前空間、セキュリティ、言語サポートを拡張する .NET Framework 1.1
Windows Forms:
.NET Framework 1.1 Provides Expanded Namespace, Security,and Language Support for Your Projects
(March 2003 Vol.18 No.3)
Chris Sells

Level :1 2 3
本記事は,WindowsフォームおよびC#についての知識があることを前提に書かれています。
SUMMARY:期待を集めていた.NET Framework 1.1のリリースに伴い,プログラマたちは手持ちのプログラミングツールに何が加わったのかを知りたがっている。
本稿では,名前空間の追加,アンマネージクライアントでのマネージコントロールのホスト,C++とJ#のデザイナサポートなど,Windowsフォーム開発関連の新機能に注目していく。Compact Frameworkへのアクセスが統合されたことや,新しいモバイルコードセキュリティ設定もこのリリースの大きな特徴である。
これらの機能とともに,複数のバージョンのCLRを取り扱うための最良の方法や,落とし穴になりそうなポイントを取り上げていく。

GotDotNet Japanの「WindowsフォームでのWindows XPテーマの使用」
http://www.gotdotnet.com/team/ja/team/windowsforms/Themes.aspx
MSDN Magazine 日本語版No.17の記事
「Visual Studio.NET:C++に.NET CLRサポートをもたらすManaged Extensions」
http://msdn.microsoft.com/msdnmag/issues/01/07/vsnet/default.aspx
MSDN Onlineの記事「You Can Take It with You」
http://msdn.microsoft.com/library/en-us/dnforms/html/winforms07182002.asp


「天候への不満は誰もが口にするが,何もできない」という諺(男心と秋の空)がある。プログラミングには,そのようなことはない。Microsoftは, いつも偉大な次期開発ツール, テクノロジーセットを開発すべく奮闘努力している。Microsoft .NET Frameworkの最新リリースであるver.1.1の予報は, 快晴である。元々はバグフィックスリリースとして計画されていたが(.NET Framework 1.0は, 昨年2月にリリースされたばかりである), ver.1.1はバグをフィックスするだけではなく,私にとって.NET Framework のなかのお気に入りの部分であるWindowsフォームに,いくつもの新機能を統合した。

 本稿は,Visual Studio .NET 2003とともに出荷されている.NET Framework 1.1の最終ベータを基礎として書かれている。正式リリースでもほとんどの機能は変わらないはずだが, 一部は間違いなく変更されるはずなので注意していただきたい。

新機能
 新しい.NET Framework SDKに含まれている「API Changes from v1.0 to v1.1」というドキュメントによれば,48 個の追加と14 個の削除があり、System.Windows.Forms名前空間には決定的な変更はない。この話を聞き、最初は48個の新機能の追加を喜び、14個の機能の削除を悲しみ,削除されたものを使っていないことを祈るような気分になるかもしれない。また,14 個の削除があるのに, 決定的な変更はないというのはどういうことなのだろうかと思うかもしれない。決定的な変更がないということは,既存のWindowsフォームコードはすべて書き換えずに動作し続けるということである。だから,削除されたものは追加されたものに対応しており,実際には,次に示すAx HostクラスのProcessDialogKeyメソッドの宣言の変更のような変更が加えられているのである。

class AxHost {
  // .NET 1.0の宣言
  protected virtual bool ProcessDialogKey(Keys keyData);
  // .NET 1.1の宣言
  protected override bool ProcessDialogKey(Keys keyData);
  ...
}
この変更は,AxHostが新しい仮想メソッドを提供するのをやめたものの,オーバーライドメソッドを提供するようになったということで,ProcessDi alogKeyは, 継承階層のより上位のクラスでvir tual宣言されるようになったことを示している。追加の大半はこの種のものであり,Windowsフォーム名前空間への変更を退屈なものに感じさせる。Windowsフォーム名前空間で特に注目すべき追加は,実際には3つだけである(それと,System.Drawing名前空間へのもう1つの追加にも注目していただきたい)。

  • System.Windows.Forms.FolderBrowserDialogクラス
  • System.Windows.Forms.Application.EnableVisualStylesメソッド
  • System.Windows.CurrencyManager.MetaDataChangedイベント
  • System.Drawing.Pringing.PrintDocument.OriginAtMarginsプロパティ
 もしこれだけでおしまいなのだとすれば,新機能を説明するために1回分の記事が必要になることはないだろう。触れておくべきことは,名前空間の追加,アンマネージクライアントでのマネージコントロールのホスティングのサポート,マネージC++とVisual J#でのWindowsフォームデザイナサポート,Compact Frameworkへの統合アクセス,新設のモバイルコードセキュリティ設定など,ほかにもたくさんある。しかし,これらの新機能に触れる前に,複数のバージョンのCLRをどのように扱ったらよいかについて説明しておこう。

1.1への移行
 私は,新しいバージョンが出るたびに,私が依存している機能を失わずに必要な機能が追加されていることを期待してきた。バージョン管理の問題がないようなふりをしてきたWin32 DLLや,バージョン管理はまったく不要であるかのようなふりをしてきたCOMとは異なり,.NET Frameworkは,コンポーネントとCLR自体の複数のバー

ジョンが同時にインストールされている状況を想定して,マルチバージョンを明示的にサポートしている。実際,Windowsアップデートが実行されているWindowsを実行していたら,.NET Framework 1.0SP2に相当するCLR ver.1.0.3705.288がインストールされているはずである。.NET Framework 1.1をインストールすると,CLRのバージョンは,.NET Framework 1.1最終ベータに相当するver.1.1.4322.510に上がる。しかし,.ver.1.1をインストールしたからといって,マシンにインストールされている既存バージョンは置き換えられない。代わりに,別個のディレクトリに両方のバージョンが共存するのである。

 実行時にロードされるCLRのバージョンは,EXEアセンブリがターゲットとしたバージョンによって決まる。そこで,.NET Framework 1.0をターゲットとしてWindowsフォームアプリケーションをビルドした場合,.NET Framework 1.1(あるいはそれ以降)がインストールされているマシンでも,そのアプリケーションのホストのためにはver.1.0のCLRがロードされる。しかし,ver.1.0がインストールされていないマシンで1.0アプリケーションを起動すると,CLR ver.1.1が自動的にロードされる。これは,1.1環境に1.0アプリケーションをロードしても問題がないことを示す.configファイルをすべてのWindowsフォーム1.0アプリケーションに要求するのを避けるためである。この動作を避けたければ,独自の.configファイルを作成し,この自動アップグレード機能をオフにすればよい。

<!-- .NET 1.0のみをサポートする-->
<configuration>
  <startup>
    <requiredRuntime version="v1.0.3705"/>
    <supportedRuntime version="v1.0.3705"/>
  </startup>
</configuration>
 この場合,CLR ver.1.0がインストールされていないマシンでver.1.0アプリケーションを起動しようとすると,ver.1.1がインストールされているかどうかに関わらず,特定のバージョンの.NET Frameworkが必要だということを示すエラーメッセージが表示される。最後に,ver.1.0をサポートしたいが,ver.1.1があるならそれを使いたい場合(たとえば,パフォーマンスが上がるなどの理由で)には,次のコードを見ていただきたい。

<!-- .NET 1.1のほうが望ましいが.NET 1.0もサポートする-->
<configuration>
  <startup>
    <requiredRuntime version="v1.0.3705"/>
    <!-- 以下のキーの順番が優先順位を示す-->
    <supportedRuntime version="v1.1.4322"/>
    <supportedRuntime version="v1.0.3705"/>
  </startup>
  ...
</configuration>
 残念ながら,話はこれで終わりではない。すべてのアセンブリには,必須アセンブリ(バージョン番号付き)のリストが含まれているので,.NET Framework 1.1のもとでアプリケーションをビルドするには,すべてのアセンブリについてver.1.1を要求することになる。1.1のもとでビルドされたver.1.0アプリケーションを1.0しかインストールされていないマシンで実行しようとすると,参照されているアセンブリの適切なバージョンを見つけられないので,実行に失敗する。そこで,ver.1.1のもとでビルドされたアプリケーションを初期バージョンのアセンブリのもとで実行できるようにするには,Figure 1に示すように,.configファイルに個々のアセンブリのためのエントリを用意しなければならない。

 これらの設定は,.NET Framework 1.0のもとで実行し,System.Windows.Formsをロードするときには,コードをver.1.1でビルドしたものであっても,ver.1.0のSystem.Windows.Formsがロードされるように指定する。この機能は,アップデートされたver.1.1ツールを安心して使えるようにしてくれるという点では好都合だが,いちいち.configファイルを設定しなければならないのは,少し苦痛である。

幸い,Visual Studio .NET 2003は,[プロジェクト]−[プロパティ]−[共通プロパティ]−[全般]の[サポートされているランタイム]から,プロジェクトの補助設定を指定できる。この設定では,ランタイムのオプションを[.NET Frameworkバージョン]ダイアログで設定できる。つまり[.NET Frameworkバージョン]ダイアログでは,Microsoft.NET Framework ver.1.1(デフォルト),ver.1.0(上級),両方の3種類のなかからどれかを選択できるのである。

 デフォルトでは,Visual Studio .NET 2003のもとでコンパイルされたアプリケーションは,CLR ver.1.1だけをターゲットとする。ver.1.0専用アプリケーションをビルドしたい場合には,ver.1.0をチェックする。最後のオプションは,両方のバージョンをサポートするが,ver.1.1を優先させる。これら3つのオプションは,どれもフレームワークアセンブリのマッピングリストを含め,適切な設定を書き込んだapp.configファイルをプロジェクトに追加するので,トラブルは避けられるはずである。作られたapp.configファイルは,プロジェクトをビルドしたときに出力ディレクトリにコピーされ,ファイル名は,CLRの要求に従って<プロジェクト名>.exe.configに変更される。

 [.NET Frameworkバージョン]ダイアログのテキストをじっくり読むと,Visual Studio .NET 2003を使っているときには,ver.1.0サポートを選択しないよう強く奨める言葉が並んでいることに気づかれることだろう。問題は,ver.1.0だけをサポートするという2番目のオプションである。Visual Studio .NET 2003は,.NET 1.0だけを要求するように適切に.configファイルを書き換えるが,IntelliSenseやコンパイラは,ver.1.0では使えなかった型やメンバーを使おうとしていることを教えてくれない。コードが1.0の機能リストに含まれていないものを使っているかどうかは,実行時まで,それも存在しない型やメソッドを,メソッドが実際に使うまで分からないのである。Visual Studio .NET 2003を使ってver.1.0をターゲットとするアプリケーションを構築するときには,本当にver.1.0のもとで実行できるかどうかを確かめるコード全体の完全なテストをする必要がある。

 ver.1.0専用アプリケーションを作るためにどうしてもVisual Studio .NET 2003を使いたいものの,正確なコンパイル時チェックやIntelliSenseも必要なら,両方を満足させられる方法がある。ただし,単に[.NET Frameworkバージョン]ダイアログを操作する以上の仕事はしなければならないので,楽な仕事ではない。まず,[プロジェクト]−[プロパティ]−[構成プロパティ]−[詳細]の「Mscorlibを使用しない」を「true」にして(デフォルトは「false」),コンパイル時にver.1.1のmscorlib.dllをロードしないようにする。次に,Visual Studio .NET 2003がプロジェクトに追加したすべてのアセンブリ参照を取り除く。これらはデフォルトでver.1.1のフレームワークディレクトリから得られるようになっているのである。最後に,[参照の追加]の「参照」ボタンを使って,ver.1.0のフレームワークディレクトリから手作業でアセンブリを選択してプロジェクト参照を追加する(mscorlib.dllとSystem.dllを含めて)。コンパイラ(およびIntelliSense)はver.1.0アセンブリを参照するようになるので,こうすれば,Visual Studio .NET 2003を使いながら,ver.1.0専用アセンブリを開発できる。

 一方,ver.1.0とver.1.1の両方をターゲットとする場合には,ver.1.1の新機能を利用したくなることがあるだろう。その場合には,System.Environment.Versionを使ってランタイムのバージョン番号をチェックしながら,ver.1.0コードから呼び出されないメソッドだけで1.1機能を使うように注意しなければならない。1.0のもとで1.1コードが呼び出されない場合でも,JITコンパイラは,メソッドが最初に呼び出されたときにすべての型とメソッドが揃っていなければ,例外を発する。Figure 2は,ver.1.1を必要とするコードを隔離する方法の1つの例である。CLRがver.1.1コードをサポートするときに限り,ver.1.1固有コードを使っているメソッドを呼び出していることに注意していただきたい。

名前空間の追加
 ver.1.1で新設されたWindowsフォーム機能を列挙したときに,CurrencyManager.MetaDataChangedイベント,PrintDocument.OriginAtMarginsプロパティ,FolderBrowserDialogクラス,Application.EnableVisualStylesメソッドの名前を出したことを思い出していただきたい。MetaDataChangedイベントは,データをバインドしているときに,ローやカラムの追加,更新のほかに,土台のメタデータが変わっているかどうかを知りたいときに役に立つ。OriginAtMarginsプロパティは,プリンタの印刷可能領域の端からではなく,用紙の端から文書の余白位置を指定したいときに役に立つ(後者のほうが分かりやすいが,.NET Framework 1.0では前者以外の選択肢はなく,ver.1.1でもデフォルトは前者である)。FolderBrowserDialogクラスは,Win32のShBrowsForFolder関数のラッパーで,期待どおりに動作する。

void browseButton_Click(object sender, EventArgs e) {
  FolderBrowserDialog dlg = new FolderBrowserDialog();
  dlg.Description = "Please choose a folder:";
  DialogResult res = dlg.ShowDialog();
  if( res == DialogResult.OK ) {
    MessageBox.Show(dlg.SelectedPath, "Selected Path");
  }
}
もちろん,FolderBrowserDialogクラスは,Visual Studio .NETツールボックスからドラッグ&ドロップできるので,プロパティブラウザを使って,初期フォルダや「新しいフォルダの作成」ボタンを表示するかどうかを設定できる。

static void Main() {
  Application.EnableVisualStyles();
  Application.Run(new Form1());
}
 EnableVisualStylesという名前からは包括的な処理をしてくれそうな感じを受けるが,フォームの個々のコントロールのFlatStyleをデフォルトのFlatStyle.StandardからFlatStyle.Systemに変更する作業も必要である。Figure 3は,Windows XPのもとで実行したときの違いを示したものである。Figure 4は,FlatStyleプロパティをサポートするコントロール(ボタン,グループボックス,ラベル)のFlatStyleプロパティをてっとり早く設定する例を示したものである。

FlatStyle
Figure3:FlatStyle

アンマネージプログラムでのマネージコントロールのホスト
 ここでは,マネージコントロールの話題に進もうとしているが,ver.1.0も,ある特定のアンマネージプログラムだけはWindowsフォームコントロールのホストをサポートしていた。それは,Microsoftインターネットエクスプローラである。その構文は,次に示すようにWindowsフォームコントロールをホストするために特別に作られた非常に特殊なものだった。

<html> <body>
  <object
    id="iectrl"
    classid="iectrl.dll#iectrl.UserControl1"
    width="100" height="100" >
  </object>
</body> </html>
 イベントをサポートするために,Windowsフォームコントロールは,interop用の特殊な属性を必要としたが,インターネットエクスプローラでは,WindowsフォームコントロールをCOMコントロールとして使うためには,通常のCOMレジストリエントリは必要としなかった。代わりに,object要素のclassid属性に,次の形式でWindowsフォームコントロールの名前を指定すればよい。

<dllName>#<namespace>.<className>
 インターネットエクスプローラは,単純に自分でWindowsフォームコントロールをロードし,それをCOMコントロールとして扱う。しかし,ver.1.0では,ほかのポピュラーなCOMコントロールホストであるMFC,Visual Basic 6.0,ATLはサポートされていなかった。ver.1.1でも,Visual Basic 6.0とATLは正式にはサポートされていないが,MFC 7.1(Visual Studio .NET 2003に含まれているMFCのバージョン)でWindowsフォームコントロールをCOMコントロールとしてホストするために,Windowsフォームチームは完璧なテストを進め,MFCは正式サポートされているアンマネージホストになった。ただし,フルサポートされているものの,フルに統合されているわけではない。Windowsフォームコントロールをサポートするには,標準のCOMコントロールの埋め込みインフラを拡大しなければならない。

 MFCのCOMコントロールサポートの中核は,CLSIDに基づき,オンデマンドでコントロールを作成するCOleControlSiteクラスにある。しかし,Windowsフォームコントロールは,ホストする前に作成しておくことになる。そこで,私はCLSIDを無視し,既存のコントロールのためのホストを作るCOleControlSite派生クラスを作った(Figure 5)。

 COMコントロールの作成のためにCWnd基底クラスのCreateControlメソッドが呼び出されると,COleControlSiteのCreateControlメソッドが呼び出される。私のCreateControl実装は,COMコントロールを作成するCreateOrLoadメソッドを呼び出さずに,WrapWinFormsControlというカスタムメソッドを呼び出すことを除けば,ほとんどが基底クラスの実装からのコピーである。私のWindowsフォームコントロールのホスティングコードは,Windowsフォームコントロールが適切なCOMインターフェイスを公開できるように.NET Frameworkが提供しているCOM Interop機能に依存している。

 また,CWinFormsControlWndクラスが使われていることに注意していただきたい。このクラスのインスタンスは,COMコントロールをホストするHWNDとWindowsフォームコントロールのIUnknownポインタを保持している。CWinFormsControlSiteは,GetControlメソッドを通じた要求に応じて,CWinFormsControlWndインスタンスが,Windowsフォームコントロールに被せたCOMの仮面についてのインターフェイスポインタを返すことを前提として動作する(Figure 6)。

 GetControlの実装は,Createメソッドに渡されるような,Windowsフォームコントロールの,キャッシュされたCOMインターフェイスポインタを返す。Createメソッドは,インターフェイスポインタを保存するとともに,CWndクラスのCreateControlメソッドを呼び出す。この呼び出しは,実際にはCWinFormsControlSiteクラスのCreateControlメソッドを呼び出す。WindowsフォームコントロールをホストしなければならないCWnd派生クラスのCreateControlSiteメソッドをオーバーライドすることによって,次のように,CWndクラスには私のCWinFormsControlSiteクラスが与えられる。

BOOL CMfcWinFormsHostDlg::CreateControlSite(...) {
  ASSERT(ppSite);
  *ppSite = new CWinFormsControlSite(this->GetControlContainer());
  return TRUE;
}
 そのようなクラスの例として,Figure 7は同じMFCダイアログにアンマネージとマネージの両方のMonthCalendarコントロールを隣り合わせにホストするダイアログボックスを示している。

 Figure 7のダイアログは,標準のMFCウィザードを使い,CreateControlSiteメソッドをオーバーライドするとともに,CWinFormsControlWndクラスのインスタンスを作成するという方法で作られている。

MFC 7.1コンテナでコントロールをホストする
Figure7:MFC 7.1コンテナでコントロールをホストする

class CMfcWinFormsHostDlg : public CDialog {
  ...
  virtual BOOL CreateControlSite(...);
  private:
  CWinFormsControlWnd m_wndWinFormsCalendar;
};
 MFCのCOMコントロール作成プロセスにフックしたら,ダイアログ作成時にWindowsフォームコントロールのインスタンスを作成できる。これは,アンマネージコードから手作業でCLRをホストし,COM Interopを使ってWindowsフォームコントロールのインスタンスを作成するという方法でも実現できる。しかし,[プロジェクト]−[プロパティ]−[構成プロパティ]−[全般]の「マネージ拡張」オプションを「はい」(デフォルトは「いいえ」)にして,C++マネージエクステンションをオンにしたほうがはるかに簡単である。こうすれば,既存のアンマネージC++クラスをマネージ化せずに,MFCアプリケーションからマネージ型(Windowsフォームコントロールを含む)を使えるようになる(Figure 8)。

 これらの操作は少し面倒だが,本稿のサンプルコードに含まれているCWinFormsControlWndとCWinFormsControlSiteヘルパークラスを使えば,面倒な部分の大半は取り除ける。MFC 7.1でWindowsフォームコントロールをホストするために,インターネットエクスプローラ5.01以上でWindowsフォームコントロールを使うために現在している以上のことをする必要はない。COMと.NETの相互運用の詳細については,Adam Nathan著の『.NET and COM : The CompleteInteroperability Guide』(Sams刊,2002年)を参照することをお勧めする。

C++とJ#のデザイナサポート
 WindowsフォームコントロールをCOMコントロールとしてホストできるのと同じように,Visual Studio .NET 2002では,C#とVisual Basic .NET以外の言語をサポートすることは不可能ではなかったが,完全に統合されていたわけでもなかった。マネージC++やJ#でWindowsフォームアプリケーションを書くことは不可能ではなかったが,デザイナサポートはなかった。すべてのコードを手作業で書かなければならなかったのである。私はWindowsフォームのファンだが,そんな仕事をしたくはない。

 幸い,Visual Studio .NET 2003は,C++やJ#を使い続けなければならないプログラマのために,マネージC++とJ#にも完全なデザイナサポートを提供するようになった。新しいプロジェクトを作成するとき,Visual C++やVisual J#を選択した場合にも,C#,Visual Basic .NETと同様に,作成するプロジェクトタイプとしてWindows コントロールライブラリ,Windowsフォームアプリケーションが表示される。Visual C++でWindowsフォームアプリケーションを作るときには,コントロールとコンポーネントが満載されたツールボックスと,それらをドラッグ&ドロップできるデザイナサーフェス,プロパティブラウザが備わったおなじみの環境が表示される。実際,違いは,ウィンドウタブの内容がForm1.csではなくForm1.hになっていることだけである。

 新しいC++Windowsフォームアプリケーションプロジェクトを作成すると,予想どおりにForm1.cpp,AssemblyInfo.cppファイルが作成されるが,それとともに,[プロジェクト]−[新しい項目の追加]でプロジェクトに追加したフォームクラスごとに.hファイルも作成される。デザイナが仕事をするのは,.hファイルであり,プログラマがコードを追加するのもここである。.cppファイルは,過ぎ去った日々の記憶にすぎず,プレコンパイル済みヘッダーと対応する.hファイルをインクルードするためにのみ存在する。おもしろいのは,ウィザードが生成したForm1.cppだけで,ここにはアプリケーションのエントリポイントが含まれている(Figure 9)。

現在C#を使ってWindowsフォームアプリケーションを開発している元C++プログラマにとって,この構文は夢から覚める思いか,悪夢に落ちる思いがすることだろう。いずれにしても,実際の動作はすべてヘッダーファイルで行なわれるものの,これは純粋なマネージC++である(Figure 10)。

 C#プログラマにとって,このコードはおなじみのものでもあるだろう。Form1カスタムクラスは,Form基底クラスから派生している。フォームのコンストラクタは,InitializeComponentクラスを呼び出す(この関数にほかのコードを追加することを認める丁寧なコメントは取り除かれているが)。Dispose関数はそこで,基底クラスを呼び出す__superキーワードを使って,目に見えないコンポーネントとの統合を処理する。InitializeComponentは,フォームとフォーム上のコントロールの初期プロパティを設定する。C#やVisual Basic .NETの場合と同様に,この関数はデザイナが所有しており,火遊び(そして黒焦げになること)が好きでない限り,そのままにしておいたほうがよい。

 ウィザードが最初のC++コードを生成したあと,デザイナは,フォームにコントロールがドラッグ&ドロップされるたびにメンバー変数を追加し,プロパティブラウザでプロパティが書き換えられるたびにInitializeComponent内のプロパティを設定し,イベントハンドラを追加する。正直なところ,Visual Basic .NET,C#プログラマがすでに使っているWindowsフォームツールと,マネージ,アンマネージC++の両方の力が合体した便利さのすべてを理解するまでは,このことは退屈な話だろう。たとえば,私がマネージC++プロジェクトで気に入っている機能の1つは,アンマネージリソースを追加できることである。これは,C#もVisual Basic .NETもサポートしていない機能である。さらに,テンプレート,多重継承,マネージ,アンマネージのコードと型の併用など,マネージC++のすでに知られている,また愛用されている特徴が加わるのである。

Compact Framework
 Visual Studio .NET 2003では,C#,Visual Basic .NET,マネージC++,J#でデスクトップアプリケーションを構築できるようになっただけではなく,C#とVisual Basic .NETでスマートデバイス用のアプリケーションを構築できるようになった。この機能は,Visual Studio .NET 2002のアドインとしてβバージョンがリリースされていたが,今回は製品のなかに組み込まれた。

 スマートデバイスアプリケーションは,pocket PCやWindows CEを実行するその他のマシンで実行される。スマートデバイスアプリケーション用のプロジェクトテンプレートを選択すると,アプリケーションかクラスライブラリを構築できるようになる。ビルドを選択すると,CLRクラスが少なく,小規模になっていることを除けば通常とまったく同じような環境が得られる。たとえば,既存のWindowsフォームゲームアプリケーションの98%は,.NET Compact Frameworkに簡単に移植できたが,それ以外については掘り下げた作業が必要になった。.NET Frameworkとは異なり,.NET Compact Frameworkは,1つの処理の方法がたかだか1つしかないので,Windowsフォームでおなじみになっている近道のなかには使えないものがある。たとえば,コントロールの背景ビットマップを設定したければ,Paintイベントで描画しなければならない。同様に,リソースからのビットマップの読み出しは,以前ほど簡単ではない。

// .NET Frameworkでリソースからビットマップをロードする
Bitmap logo = new Bitmap(this.GetType(), "sblogo.PNG");

// Compact Frameworkでリソースからビットマップをロードする
Assembly assem = Assembly.GetExecutingAssembly();
string file = "PocketWahoo.sblogo.PNG";
Bitmap logo = new
Bitmap(assem.GetManifestResourceStream(file));
しかし,エミュレートされたデバイスではあるものの,ほかのデバイ

スでWindowsフォームアプリケーションを実行できるのは,ほかに代

えがたい機能である(Figure 11)。

モバイルコードのセキュリティ設定
 おもしろいと感じていただけるかもしれない細部としてはもう1つ,コードとはまったく関係ないが,WebからダウンロードされるWindowsフォームコントロールと,スマートクライアントのセキュリティ設定である。ver.1.0の.NET Frameworkは,インターネットエクスプローラで,COMコントロールと同様にWindowsフォームコントロールをホストできるというすばらしい機能を提供していた。さらに,ver.1.0は,スマートクライアント,つまりWeb越しに実行されるクライアントアプリケーションという考え方さえ導入した。まだ試したことのない読者は,仮想ディレクトリを作成し,そこにWindowsフォームアプリケーションをコピーして,[スタート]−[ファイル名を指定して実行]からhttp: //localhost/itweb/hr452.exeのようなURLにジャンプしてみていただきたい。ローカルマシンにアプリケーションがダウンロードされ,スタンドアロンのクライアントアプリケーションのように実行される。ただし,アプリケーションがどこから起動されたかによって,実行できることに制限が加えられる(スマートクライアントの詳細については,SDKリファレンスを参照していただきたい)。

 もちろん,Webを介したコードのダウンロードとホストの両方の手段には,セキュリティに関して緻密な配慮が必要になる。コードには,フレンドリなイントラネットから送られてくるものもあれば,敵意に満ちたインターネットから送られてくるものもある。困ったことが起きないようにするために,.NET FrameworkのCAS(コードアクセスセキュリティ)モデルには,出自に基づいて個々のアセンブリに部分的に信用を置くセキュリティサンドボックスがある。ver.1.0 SP0では,イントラネットとインターネットの両方のゾーンから送られてきたアセンブリの実行を認めていたが,インターネットからのアセンブリに与えられた許可は,イントラネットアセンブリと比べてかなり小さいものだった。Microsoftは,ver.1.0 SP1から方針を変更し,インターネットから送られてきたコードを無効にするように設定を変更した(有効にするように戻すことはできるが)。より安全性を追求したver.1.1では,Microsoftはインターネットコードに与えられる許可を減らすことなく,インターネットコードの実行をデフォルトでオンに戻した。しかし,話はそれだけでは終わらない。.NET Framework ver.1.1

は,COMのAuthenticodeモデルの復活も行なったのである。

 COM Authenticodeモデルでは,ユーザーがコードの実行を認めたら,ユーザーに与えられた許可(ほとんどのユーザーは管理者特権を持っている)の範囲内で,コードはほとんど何でもすることができる。コードが何か悪いことをしたら,専門家チームがそれを追跡し,証明書を見つけ,コードを書いた悪者を罰するのである。それに対し,.NETのCASモデルは,ユーザーに問い合わせを行なわない代わりに,ローカルハードドライブ以外の場所から送り込まれたコードには限られた許可セットしか与えないという点で,予防的な動作をする。実践的には,どちらのモデルにも意味がある。もちろん,CASは困ったことが起きないようにするうえで効果的である。それに対し,Authenticodeは,マシンの外から送り込まれたコードが実行されようとしていることをユーザーに知らせ,それでよいかどうかを尋ねられる。問い合わせをするかどうかは,COMコントロールについて問い合わせをするかどうかを決めるのと同じインターネットセキュリティ設定で決められる。インターネットゾーンから送られてきたコードのデフォルト設定は,ver.1.1最終ベータの段階では,Figure 12に示すようなものになっている。

ver.1.1のセキュリティ設定
Figure12:ver.1.1のセキュリティ設定

 ここからも分かるように,インターネットゾーンからのコードを実行するときのデフォルトは,問い合わせなしである。イントラネットゾーンも同様である。ActiveX/COMコントロールのデフォルトは,署名付きコントロールについては問い合わせあり,署名なしコントロールについては無効なので,それと比べれば緩やかな設定だと言える。もちろん,COMコントロールについては,セキュリティの手段はAuthenticodeだけだが,.NET Frameworkでは,CASがユーザーを守り続ける。

私たちはどこにいるのか

Chris Sells:Chris Sellsは、.NET FrameworkとCOMによる分散アプリケーションを専門とするフリーのコンサルタントで、インストラクタ、ライターである。Chrisと彼が手がけたさまざまなプロジェクトの詳細については、http://www.sellsbrothers.comを参照していただきたい。



グレープシティ(株)社長インタビュー
 back to top Last Updated: 2004/07/26     
Copyright (C) 2001 ASCII Corporation. All rights reserved.
プライバシーポリシー