インターネット上の ActiveX コントロール
更新 : 2007 年 11 月
ActiveX コントロールの仕様は、OLE コントロールを元に更新したものです。コントロールは、インターネット上の COM 対応の Web ブラウザなど、各種のコンテナで使用できるプログラミング可能なソフトウェア コンポーネントを開発するための基本的なアーキテクチャです。ActiveX コントロールは、インターネット コントロールとして、または Web ページの一部として使えます。その機能を Active ドキュメントに追加することもできます。Web ページのコントロール間では、スクリプトを通じて相互に情報をやりとりできます。
ActiveX コントロールは、インターネットに限らず、すべてのコンテナで使用できます。ただし、そのコンテナが要求するインターフェイスをサポートすることが条件です。
ActiveX コントロールの利点は、以下のとおりです。
従来の OLE コントロールよりもインターフェイスの数が減ります。
常に埋め込み先編集が有効化された、ウィンドウなしのコントロールとしても機能できます。
ActiveX コントロールとして機能するための条件は、次のとおりです。
IUnknown インターフェイスをサポートする。
COM オブジェクトである。
DLLRegisterServer と DLLUnRegisterServer をエクスポートする。
機能に応じたその他のインターフェイスをサポートする。
既存のコントロールをインターネット対応にする
インターネット環境で効率よく動作するコントロールをデザインするには、インターネットの転送速度が比較的遅いことを考慮に入れます。既存のコントロールを使用することもできますが、コードのサイズを小さくし、コントロール プロパティを非同期でダウンロードできるようにするには、多少の手間をかける必要があります。
コントロールのパフォーマンスを向上させるには、以下のヒントを参考にして効率を高める工夫をします。
「MFC ActiveX コントロール : 最適化」で説明されている手法を実装します。
コントロールのインスタンス化の方法について検討します。
ほかのプログラムの実行を中断しないように、非同期でダウンロードします。
小さなブロック単位でデータをダウンロードします。
ビットマップやビデオ データなどの大きなストリームをダウンロードする場合は、コンテナを利用してコントロールのデータに非同期的にアクセスします。データを同時に取得しているほかのコントロールと協調して、部分的に少しずつデータを取得します。コードも非同期的にダウンロードできます。
コードとプロパティをバックグランドでダウンロードします。
できるだけ速くユーザー インターフェイスをアクティブにします。
永続データの格納方法について検討します。永続データには、プロパティおよびデータ サイズが大きい BLOB (ビットマップ イメージやビデオ データなど) が含まれます。
大きなビットマップや AVI ファイルなど、大量の永続データを持つコントロールは、ダウンロードの方法に注意を要します。ドキュメントまたはページをすぐに表示して、コントロールがバックグラウンドでデータを取得している間に、ユーザーがページを操作できるようにします。
効率的なルーチンを作成して、コードのサイズを小さくし、実行時間を短くします。
インターネット環境で使用するには、永続データのバイト数が少ない小さなボタンやラベル コントロールが適しています。ブラウザ内ですばやく動作するからです。
コンテナへの進行状況の通知について検討します。
コンテナに非同期的なダウンロードの進行状況を通知します。たとえば、ユーザーがどの時点でページの操作を開始できるか、ダウンロードがいつ完了したかなどを知らせます。コンテナは、パーセンテージなどの進行状況をユーザーのために表示します。
クライアント コンピュータでのコントロールの登録方法について検討します。
ActiveX コントロールを新規作成する
アプリケーション ウィザードでコントロールを新規作成する場合は、通常の最適化処理のほかに非同期モニカのサポートを指定できます。コントロール プロパティの非同期ダウンロードをサポートするには、次の手順に従ってください。
MFC ActiveX コントロール ウィザードを使ってプロジェクトを作成するには
[ファイル] メニューの [新規作成] をクリックします。
[Visual C++ プロジェクト] の [MFC ActiveX コントロール ウィザード] を選択し、プロジェクトに名前を付けます。
[コントロールの設定] ページの [非同期でプロパティを読み込む] を選択します。このオプションを選択すると、コントロールの ReadyState プロパティと ReadyStateChange イベントが設定されます。
[ウィンドウなしでアクティブ] など、別の最適化処理を選択することもできます。ウィンドウなしのアクティベーションについては、「MFC ActiveX コントロール : 最適化」を参照してください。
[完了] をクリックして、プロジェクトを作成します。
CDataPathProperty の派生クラスを作成するには
CDataPathProperty の派生クラスを作成します。
各ソース ファイルにあるコントロールのヘッダー ファイルの前に、このクラスのヘッダー ファイルをインクルードします。
このクラス内で、OnDataAvailable をオーバーライドします。この関数は、データが表示できる状態のときに必ず呼び出されます。表示できる状態のデータは、選択した方法で処理できます。たとえば、データを少しずつ表示していくことができます。
次に示すコードは、エディット コントロールにデータを少しずつ表示していく簡単な例です。BSCF_FIRSTDATANOTIFICATION フラグを使用してエディット コントロールをクリアしていることに注意してください。
void CMyDataPathProperty::OnDataAvailable(DWORD dwSize, DWORD bscfFlag) { CListCtrl list_ctrl; CEdit* edit = list_ctrl.GetEditControl(); if ((bscfFlag & BSCF_FIRSTDATANOTIFICATION) && edit->m_hWnd) { edit->SetSel(0, -1); edit->Clear(); } if (dwSize > 0) { CString string; LPTSTR str = string.GetBuffer(dwSize); UINT nBytesRead = Read(str, dwSize); if (nBytesRead > 0) { string.ReleaseBuffer(nBytesRead); edit->SetSel(-1, -1); edit->ReplaceSel(string); } } }
CListCtrl クラスを使用するには、AFXCMN.H をインクルードする必要があります。
コントロール全体の状態が、読み込み中から初期化、ユーザー通信中などに移行した場合は、COleControl::InternalSetReadyState を呼び出します。コントロールのデータ パス プロパティが 1 つだけの場合は、ダウンロードの完了をコンテナに知らせるコードを BSCF_LASTDATANOTIFICATION に追加できます。次に例を示します。
if (bscfFlag & BSCF_LASTDATANOTIFICATION) { GetControl()->InternalSetReadyState(READYSTATE_COMPLETE); }
OnProgress をオーバーライドします。OnProgress では、最大範囲を示す数字とダウンロードの現在の進行状況を示す数字が渡されます。これらの数字は、完了のパーセンテージとして使用され、ステータスに表示されます。
次に、作成した派生クラスを使用するコントロールにプロパティを追加します。
プロパティを追加するには
[クラス ビュー] で、ライブラリ ノードの下のインターフェイスを右クリックし、[追加] をポイントします。次に、[プロパティの追加] をクリックします。プロパティの追加ウィザードが起動します。
プロパティの追加ウィザードで、[Get/Set メソッド] をクリックし、[プロパティ名] ボックスにプロパティ名 (「EditControlText」など) を入力します。次に、[プロパティの種類]の [BSTR] を選択します。
[完了] をクリックします。
CDataPathProperty の派生クラスを ActiveX コントロール クラスのメンバ変数として宣言します。
CMyDataPathProperty EditControlText;
Get メソッドと Set メソッドを実装します。Get の場合は、文字列を返します。Set の場合は、プロパティを読み込んで SetModifiedFlag を呼び出します。
BSTR CMFCActiveXControlCtrl::GetEditControlText(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CString strResult; strResult = EditControlText.GetPath(); return strResult.AllocSysString(); } void CMFCActiveXControlCtrl::SetEditControlText(LPCTSTR newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); Load(newVal, EditControlText); SetModifiedFlag(); }
DoPropExchange に、次の行を追加します。
PX_DataPath(pPX, _T("DataPath"), EditControlText);
ResetData をオーバーライドし、次の行を追加してコントロールをリセットするようにプロパティに知らせます。
EditControlText.ResetData();
CDataPathProperty と CCachedDataPathProperty のどちらを派生元にするかを決める
前の例では、コントロールのプロパティを CDataPathProperty から派生する手順を示しました。この方法は、頻繁に変更されるリアルタイムのデータをダウンロードし、現在の値以外のデータを保持しない場合に適しています。株相場を表示するティッカー コントロールなどが該当します。
コントロールのプロパティは、CCachedDataPathProperty から派生することもできます。この場合、ダウンロードされたデータは、メモリ ファイルにキャッシュされます。この方法は、すべてのダウンロードされたデータを保持する場合に適しています。ビットマップを少しずつ描画していくコントロールなどがこれに該当します。この場合、データはクラスのメンバ変数に含まれます。
CMemFile m_Cache;
ActiveX コントロール クラスでは、このメモリ マップト ファイルを OnDraw で使用して、データを表示できます。ActiveX コントロールの CCachedDataPathProperty の派生クラスで、メンバ関数 OnDataAvailable をオーバーライドし、基本クラスに実装されたコントロールを呼び出した後に、コントロールを無効化します。
void CMyCachedDataPathProperty::OnDataAvailable(DWORD dwSize, DWORD bscfFlag)
{
CCachedDataPathProperty::OnDataAvailable(dwSize, bscfFlag);
GetControl()->InvalidateControl();
}
ActiveX コントロールを使用して非同期にデータをダウンロードする
ネットワークを通じてデータをダウンロードする場合は、非同期で行うことをお勧めします。非同期でダウンロードすると、転送データが大量の場合でも、接続が遅い場合でも、クライアント上のほかのプロセスの実行は中断されません。
非同期モニカを使用すると、ネットワークを通じてデータを非同期でダウンロードできます。非同期モニカでの Read 操作は、操作が完了していなくてもすぐに制御を返します。
たとえば、1KB のファイルに対して Read が非同期に呼び出されたり、用意できているデータが 10 バイトだけだとしても、Read はブロックしません。しかし、現在使用できる 10 バイトを返します。
非同期モニカは、CAsyncMonikerFile クラスを使用して実装します。ただし、ActiveX コントロールでは、CAsyncMonikerFile の派生クラス CDataPathProperty を使用して、コントロールの非同期プロパティを実装できます。
ASYNDOWN サンプルは、タイマを使用してデータを読み取る非同期ループの設定例です。ASYNDOWN は、サポート技術情報の文書「HOWTO: AsyncDown Demonstrates Asynchronous Data Download (Q177244)」で詳しく説明されており、Microsoft Download Center からダウンロードできます。Microsoft Download Center からのファイルのダウンロードについては、サポート技術情報の「How to Obtain Microsoft Support Files from Online Services (Q119591)」を参照してください。サポート技術情報の文書は、MSDN ライブラリ CD-ROM または https://support.microsoft.com/support で参照できます。
ASYNDOWN で使用している基本的な手法では、CDataPathProperty::OnDataAvailable でタイマを設定して、いつデータが利用できるかを示します。アプリケーションは、タイマ メッセージを受け取ると 128 バイトのデータ ブロックを読み取り、エディット コントロールに表示します。タイマ メッセージの処理時にデータがない場合は、タイマがオフになります。後でデータが到着すると、OnDataAvailable によってタイマがオンになります。
Web ページにコントロールを表示する
次の例は、Web ページにコントロールを挿入するためのオブジェクト タグと属性を示しています。
<OBJECT
CLASSID="clsid:FC25B780-75BE-11CF-8B01-444553540000"
CODEBASE="/ie/download/activex/iechart.ocx"
ID=chart1
WIDTH=400
HEIGHT=200
ALIGN=center
HSPACE=0
VSPACE=0
>
<PARAM NAME="BackColor" value="#ffffff">
<PARAM NAME="ForeColor" value="#0000ff">
<PARAM NAME="url" VALUE="/ie/controls/chart/mychart.txt">
</OBJECT>
既存の OLE コントロールを更新して ActiveX コントロールの新機能を使用する
Visual C++ 4.2 より前のバージョンで作成された OLE コントロールを更新すると、パフォーマンスを向上させ、機能を強化できます。更新の詳細については、「MFC ActiveX コントロール : 最適化」を参照してください。
既存のコントロールに非同期プロパティのサポートを追加するには、ReadyState プロパティと ReadyStateChange イベントを手作業で追加します。コントロールのコンストラクタに、次の行を追加してください。
m_lReadyState = READYSTATE_LOADING;
コードのダウンロード時に ReadyState プロパティを更新するには、COleControl::InternalSetReadyState を呼び出します。たとえば、CDataPathProperty 派生クラスの OnProgress のオーバーライドから InternalSetReadyState を呼び出すことができます。
次に、「ActiveX コントロールを新規作成する」の手順に従います。