インターネット上の ActiveX コントロール

ActiveX コントロールは、OLE コントロールの仕様を更新したバージョンです。

重要

ActiveX は、新しい開発には使用すべきではないレガシ テクノロジです。 詳細については、「ActiveX コントロール」を参照してください。

コントロールは、プログラミング可能なソフトウェア コンポーネントを開発するための主要なアーキテクチャです。インターネットにおける COM 対応 Web ブラウザーを含め、種々のコンテナーに使用できます。 ActiveX コントロールはインターネット コントロールにもなり、その機能をアクティブ ドキュメントに追加したり、Web ページの一部として使用したりすることができます。 Web ページ上のコントロールは、スクリプトを使用して互いにやり取りすることができます。

ActiveX コントロールは、インターネットに限定されません。 コンテナーに必要なインターフェイスをサポートしていれば、ActiveX コントロールはどのようなコンテナーでも使用できます。

ActiveX コントロールにはいくつかの利点があります。その例を次に示します。

  • 必要なインターフェイスが以前の OLE コントロールよりも少ない。

  • ウィンドウレスにしたり、常時インプレース アクティブにしたりできる。

ActiveX コントロールは次の要件を満たす必要があります。

  • IUnknown インターフェイスをサポートする。

  • COM オブジェクトである。

  • DLLRegisterServerDLLUnRegisterServer をエクスポートする。

  • 機能に必要なインターフェイスを別途サポートする。

既存のコントロールをインターネット対応にする

インターネットでは伝送速度があまり高くないため、インターネット環境で適切に動作するコントロールを設計するためには考慮すべき事柄があります。 既存のコントロールを使用することもできますが、コードのサイズを小さくし、コントロールのプロパティを非同期的にダウンロードできるようにするために従うべき手順があります。

コントロールのパフォーマンスを高めるために、効率の考慮事項についてのこれらのヒントに従ってください。

  • ActiveX コントロールの最適化に関する記事で説明されている手法を導入する。

  • コントロールがインスタンス化される方法を検討する。

  • 非同期にする。つまり他のプログラムの動作を妨げない。

  • データは小さいブロックでダウンロードする。

    ビットマップやビデオ データなど、大きなストリームをダウンロードするときは、コンテナーと連携してコントロールのデータに非同期的にアクセスします。 同時にデータを取得している他のコントロールと強調しながら、データを増分形式やプログレッシブ形式で取得してください。 コードを非同期的にダウンロードすることもできます。

  • コードやプロパティをバックグラウンドでダウンロードする。

  • ユーザーインターフェイスをできるだけ早くアクティブにする。

  • 永続データ、つまりプロパティと大きなデータ BLOB (ビットマップ画像、ビデオ データなど) の両方の格納方法を検討する。

    大きなビットマップや AVI ファイルなど、永続データのサイズが極端に大きいコントロールはダウンロード方法に注意が必要です。 ドキュメントまたはページはできるだけ早く表示してください。そうすればコントロールがバックグラウンドでデータを取得している間、ユーザーはページを操作することができます。

  • コード サイズと実行時間を抑えるために効率的なルーチンを記述する。

    インターネット環境では、永続データが数バイトのみの小さなボタン コントロールとラベル コントロールが適しており、ブラウザー内でもうまく機能します。

  • 進行状況をコンテナーに伝達することを検討する。

    ユーザーがいつページを操作できるようになり、いつダウンロードが完了するかなど、非同期ダウンロードの進行状況をコンテナーに通知します。 コンテナーからユーザーに進行状況 (完了した割合など) を表示できます。

  • クライアント コンピューターへのコントロールの登録方法を考慮する。

新しい ActiveX コントロールを作成する

アプリケーション ウィザードを使用して新しいコントロールを作成するときに、非同期モニカーなどの最適化サポートを有効にすることを選択できます。 コントロールのプロパティを非同期的にダウンロードするためのサポートを追加するには、これらの手順に従います。

MFC ActiveX コントロール ウィザードを使用してプロジェクトを作成するには

  1. [ファイル] メニューの [新規] をクリックします。

  2. Visual Studio C++ プロジェクトから [MFC ActiveX コントロール ウィザード] を選択し、プロジェクトに名前を付けます。

  3. [コントロールの設定] ページで [Loads properties asynchronously] (プロパティを非同期的に読み込む) を選択します。 このオプションを選択すると、準備完了状態プロパティと準備完了状態変更イベントが自動的に設定されます。

    ウィンドウレスのアクティブ化 (ActiveX コントロールの最適化に関する記事を参照) など、他の最適化を選択することもできます。

  4. [完了] を選択して、プロジェクトを作成します。

CDataPathProperty から派生したクラスを作成するには

  1. CDataPathProperty から派生したクラスを作成します。

  2. コントロールのヘッダー ファイルが含まれている各ソース ファイルについて、コントロールのヘッダー ファイルの前に、このクラスのヘッダー ファイルを追加します。

  3. このクラスで 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 をインクルードする必要があるので注意してください。

  4. コントロールの全体的な状態が変化したら (loading から initialized または user interactive など)、COleControl::InternalSetReadyState を呼び出します。 コントロールにあるデータ パス プロパティが 1 つのみの場合は、ダウンロードの完了をコンテナーに通知するコードを BSCF_LASTDATANOTIFICATION に追加できます。 次に例を示します。

    if (bscfFlag & BSCF_LASTDATANOTIFICATION)
    {
       GetControl()->InternalSetReadyState(READYSTATE_COMPLETE);
    }
    
  5. OnProgress をオーバーライドします。 OnProgress には、最大範囲を表す数値と現在のダウンロードの進行状況を表す数値が渡されます。 これらの数値を使用して、完了率などの状態をユーザーに表示できます。

次の手順では、先ほど派生したクラスを使用するためのプロパティをコントロールに追加します。

プロパティを追加するには

  1. クラス ビューで、ライブラリ ノードの下にあるインターフェイスを右クリックし、[追加][プロパティの追加] の順に選択します。 プロパティ追加ウィザードが起動します。

  2. プロパティ追加ウィザード[Set/Get Methods] (Set/Get メソッド) をクリックし、プロパティ名 (「EditControlText」など) を入力して、[プロパティの型] に BSTR を選択します。

  3. [完了] をクリックします。

  4. CDataPathProperty から派生したクラスのメンバー変数を ActiveX コントロールのクラスに宣言します。

    CMyDataPathProperty EditControlText;
    
  5. 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();
    }
    
  6. DoPropExchange に、次の行を追加します。

    PX_DataPath(pPX, _T("DataPath"), EditControlText);
    
  7. 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 コントロールを使用してデータを非同期的にダウンロードする

ネットワーク経由でのデータのダウンロードは、非同期的に行う必要があります。 その利点は、転送するデータが大量にある場合や接続速度が遅い場合でも、クライアント上の他のプロセスがダウンロード プロセスによってブロックされないことです。

非同期モニカーは、データをネットワーク経由で非同期的にダウンロードする手段となります。 非同期モニカーでの読み取り操作は、操作が完了していなくてもすぐに制御が返されます。

たとえば、1K ファイルの 10 バイトしか利用できない場合でも、読み取りを非同期で呼び出せば、読み取りはブロックされず、その時点で利用可能な 10 バイトが返されます。

非同期モニカーCAsyncMonikerFile クラスを使用して実装します。 ただし ActiveX コントロールでは、CAsyncMonikerFile から派生した CDataPathProperty クラスを使用することで、非同期コントロールのプロパティを簡単に実装できます。

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 コントロールの機能を使用する

OLE コントロールが Visual C++ バージョン 4.2 未満で作成されている場合、いくつかの手順を実施することで、そのパフォーマンスと機能を高めることができます。 その変更について詳しくは、ActiveX コントロールの最適化に関するページを参照してください。

既存のコントロールに非同期プロパティのサポートを追加する場合、準備完了状態プロパティと ReadyStateChange イベントを自分で追加する必要があります。 コントロールのコンストラクターで、次のコードを追加します。

m_lReadyState = READYSTATE_LOADING;

コードがダウンロードされたら、COleControl::InternalSetReadyState を呼び出して準備完了状態を更新します。 InternalSetReadyState の呼び出しは、たとえば、CDataPathProperty から派生したクラスの OnProgress オーバーライドから行うことができます。

関連項目

MFC インターネット プログラミングの作業
MFC インターネット プログラミングの基礎