MFC ActiveX コントロール : 高度なトピック
この記事では、ActiveX コントロールの開発に関連する高度なトピックについて説明します。 これには以下が含まれます。
重要
ActiveX は、新しい開発には使用すべきではないレガシ テクノロジです。 ActiveX に取って代わる最新のテクノロジの詳細については、「ActiveX コントロール」を参照してください。
ActiveX コントロールでのデータベース クラスの使用
ActiveX コントロール クラスはクラス ライブラリの一部であるため、MFC データベース クラスを使用する ActiveX コントロールを開発するにあたって、標準の MFC アプリケーションでデータベース クラスを使用する場合と同じ手順と規則を適用できます。
MFC データベース クラスの一般的な概要については、MFC データベース クラス (DAO および ODBC) に関するページを参照してください。 この記事では、MFC ODBC クラスと MFC DAO クラスの両方について紹介し、どちらかの詳細について説明します。
Note
DAO は、Office 2013 でサポートされています。 DAO 3.6 は最終バージョンであり、古いバージョンと見なされます。 Visual C++ 環境およびウィザードでは DAO はサポートされていません (ただし、DAO クラスは含まれており、引き続き使用できます)。 Microsoft は、新しいプロジェクトには OLE DB テンプレートまたは ODBC および MFC を使用することをお勧めします。 DAO は、既存のアプリケーションを保守するためにのみ使用してください。
パラメーター化されたプロパティの実装
パラメーター化されたプロパティ (プロパティ配列とも呼ばれます) は、同種の値のコレクションをコントロールの単一のプロパティとして公開するためのメソッドです。 たとえば、パラメーター化されたプロパティを使用して、配列またはディクショナリをプロパティとして公開できます。 Visual Basic では、配列表記を使用してこのようなプロパティにアクセスします。
x = o.Array(2, 3) ' gets element of 2D array
o.Array(2, 3) = 7 ' sets element of 2D array
パラメーター化されたプロパティを実装するには、プロパティの追加ウィザードを使用します。 プロパティの追加ウィザードでは、Get および Set 関数のペアを追加することによってプロパティを実装します。これにより、コントロール ユーザーは、上記の表記法または標準的な方法を使用してプロパティにアクセスできるようになります。
パラメーター化されたプロパティには、メソッドやプロパティと同様に、許可されるパラメーターの数に制限があります。 パラメーター化されたプロパティの場合、パラメーターは 15 個に制限されます (プロパティ値を格納するために 1 つのパラメーターが予約されています)。
次の手順では、整数の 2 次元配列としてアクセスできる、Array と呼ばれるパラメーター化されたプロパティを追加します。
プロパティの追加ウィザードを使用してパラメーター化されたプロパティを追加するには
コントロールのプロジェクトを読み込みます。
[クラス ビュー] で、コントロールのライブラリ ノードを展開します。
コントロールのインターフェイス ノード (ライブラリ ノードの 2 番目のノード) を右クリックし、ショートカット メニューを開きます。
ショートカット メニューから、[追加]、[プロパティの追加] の順にクリックします。
[プロパティ名] ボックスに、「
Array
」と入力します。[プロパティの種類] ボックスで、[
short
] を選択します。[実装の種類] として、[Get/Set メソッド] をクリックします。
[Get 関数] および [Set 関数] ボックスで、Get および Set 関数の一意の名前を入力するか、既定の名前を受け入れます。
[パラメーター名] および [パラメーターの種類] コントロールを使用して、row (short 型) というパラメーターを追加します。
column (short 型) という 2 番目のパラメーターを追加します。
[完了] をクリックします。
プロパティの追加ウィザードによって加えられる変更
カスタム プロパティを追加すると、プロパティの追加ウィザードによって、コントロール クラスのヘッダー (.H) ファイルと実装 (.CPP) ファイルに変更が加えられます。
コントロール クラスの .H ファイルに次の行が追加されます。
SHORT GetArray(SHORT row, SHORT column);
void SetArray(SHORT row, SHORT column, SHORT newVal);
このコードでは、GetArray
と SetArray
という 2 つの関数を宣言しています。これにより、ユーザーは、プロパティにアクセスするときに特定の行と列を要求できるようになります。
さらに、プロパティの追加ウィザードにより、コントロール クラスの実装 (.CPP) ファイルにあるコントロール ディスパッチ マップに次の行が追加されます。
DISP_PROPERTY_PARAM_ID(CMyAxUICtrl, "Array", dispidArray, GetArray, SetArray, VT_I2, VTS_I2 VTS_I2)
最後に、GetArray
および SetArray
関数の実装が .CPP ファイルの末尾に追加されます。 ほとんどの場合、プロパティの値を返すように Get 関数を変更します。 Set 関数には、通常、プロパティの変更前または変更後に実行する必要のあるコードが含まれます。
このプロパティを使用するには、パラメーター化されたプロパティの値を格納するための short
型の 2 次元配列メンバー変数をコントロール クラスで宣言します。 次に、パラメーターで示された適切な行と列に格納されている値を返すように Get 関数を変更し、行と列のパラメーターによって参照される値を更新するように Set 関数を変更します。
ActiveX コントロールでのエラーの処理
コントロールでエラー状態が発生した場合は、コントロール コンテナーにエラーを報告することが必要になる場合があります。 エラーを報告するには、エラーが発生した状況に応じて 2 つの方法があります。 プロパティの Get 関数または Set 関数内、または OLE オートメーション メソッドの実装内でエラーが発生した場合、コントロールは、COleControl::ThrowError を呼び出して、エラーが発生したことをコントロール ユーザーに通知する必要があります。 それ以外のときにエラーが発生した場合、コントロールは、COleControl::FireError を呼び出して、ストック エラー イベントを発生させる必要があります。
発生したエラーの種類を示すには、コントロールは、エラー コードを ThrowError
または FireError
に渡す必要があります。 エラー コードは、32 ビット値の OLE 状態コードです。 可能であれば、OLECTL.H ヘッダー ファイルで定義されている標準のコード セットからエラー コードを選択します。 次の表に、これらのコードを要約します。
ActiveX コントロール エラー コード
エラー | 説明 |
---|---|
CTL_E_ILLEGALFUNCTIONCALL | 関数呼び出しが無効です |
CTL_E_OVERFLOW | オーバーフロー |
CTL_E_OUTOFMEMORY | メモリ不足 |
CTL_E_DIVISIONBYZERO | 0 で除算しました |
CTL_E_OUTOFSTRINGSPACE | 文字列スペースが不足しています。 |
CTL_E_OUTOFSTACKSPACE | スタック領域が不足しています。 |
CTL_E_BADFILENAMEORNUMBER | ファイル名または番号が正しくありません。 |
CTL_E_FILENOTFOUND | ファイルが見つかりません |
CTL_E_BADFILEMODE | ファイル モードが正しくありません。 |
CTL_E_FILEALREADYOPEN | ファイルは既に開かれています。 |
CTL_E_DEVICEIOERROR | デバイス I/O エラーです。 |
CTL_E_FILEALREADYEXISTS | ファイルは既に存在します |
CTL_E_BADRECORDLENGTH | レコード長が正しくありません。 |
CTL_E_DISKFULL | ディスクの空き容量が不足しています |
CTL_E_BADRECORDNUMBER | レコード番号が正しくありません |
CTL_E_BADFILENAME | ファイル名が正しくありません |
CTL_E_TOOMANYFILES | ファイルが多すぎます。 |
CTL_E_DEVICEUNAVAILABLE | デバイスを使用できません |
CTL_E_PERMISSIONDENIED | アクセス許可は拒否されました |
CTL_E_DISKNOTREADY | ディスクが準備されていません |
CTL_E_PATHFILEACCESSERROR | パスまたはファイル アクセス エラー |
CTL_E_PATHNOTFOUND | パスが見つかりません。 |
CTL_E_INVALIDPATTERNSTRING | 無効なパターン文字列 |
CTL_E_INVALIDUSEOFNULL | NULL の使用方法が無効です |
CTL_E_INVALIDFILEFORMAT | 無効なファイル形式です |
CTL_E_INVALIDPROPERTYVALUE | プロパティ値が無効です |
CTL_E_INVALIDPROPERTYARRAYINDEX | プロパティ配列のインデックスが無効です |
CTL_E_SETNOTSUPPORTEDATRUNTIME | Set は実行時にはサポートされません |
CTL_E_SETNOTSUPPORTED | Set はサポートされません。読み取り専用のプロパティです。 |
CTL_E_NEEDPROPERTYARRAYINDEX | プロパティ配列のインデックスが必要です。 |
CTL_E_SETNOTPERMITTED | Set は使用できません |
CTL_E_GETNOTSUPPORTEDATRUNTIME | Get は実行時にはサポートされません |
CTL_E_GETNOTSUPPORTED | Get はサポートされません (書き込み専用のプロパティです) |
CTL_E_PROPERTYNOTFOUND | プロパティが見つかりません。 |
CTL_E_INVALIDCLIPBOARDFORMAT | クリップボードの形式が無効です |
CTL_E_INVALIDPICTURE | 無効な画像です |
CTL_E_PRINTERERROR | プリンター エラーです |
CTL_E_CANTSAVEFILETOTEMP | ファイルを TEMP に保存できません |
CTL_E_SEARCHTEXTNOTFOUND | 検索文字列が見つかりませんでした |
CTL_E_REPLACEMENTSTOOLONG | 置換後の文字列が長すぎます |
必要に応じて、CUSTOM_CTL_SCODE マクロを使用して、標準コードのいずれにも該当しない条件のカスタム エラー コードを定義します。 このマクロのパラメーターは、1000 から 32767 までの整数である必要があります。 次に例を示します。
#define MYCTL_E_SPECIALERROR CUSTOM_CTL_SCODE(1000)
ActiveX コントロールを作成して既存の VBX コントロールを置き換える場合は、エラー コードの互換性を確保するために、VBX コントロールで使用されるのと同じ数値を使用して、ActiveX コントロールのエラー コードを定義します。
コントロールでの特殊なキーの処理
場合によっては、特定のキーストロークの組み合わせを特別な方法で処理することが必要になることがあります。たとえば、複数行のテキスト ボックス コントロールで Enter キーが押されたときに改行を挿入することや、方向キー ID が押されたときに編集コントロールのグループ間を移動することができます。
ActiveX コントロールの基底クラスが COleControl
の場合は、CWnd::PreTranslateMessage をオーバーライドして、コンテナーが処理する前にメッセージを処理することができます。 この手法を使用して PreTranslateMessage
のオーバーライドでメッセージを処理する場合は、常に TRUE を返します。
次のコード例は、方向キーに関連するメッセージを処理するための 1 つの方法を示しています。
BOOL CMyAxUICtrl::PreTranslateMessage(MSG* pMsg)
{
BOOL bHandleNow = FALSE;
switch (pMsg->message)
{
case WM_KEYDOWN:
switch (pMsg->wParam)
{
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
bHandleNow = TRUE;
break;
}
if (bHandleNow)
{
OnKeyDown((UINT)pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
}
break;
}
return bHandleNow;
}
ActiveX コントロールのキーボード インターフェイスを処理する方法の詳細については、ActiveX SDK のドキュメントを参照してください。
実行時に表示されないダイアログ コントロールへのアクセス
ユーザー インターフェイスを備えない、実行時に表示されないダイアログ コントロールを作成できます。 実行時に表示されない ActiveX コントロールをダイアログ ボックスに追加し、CWnd::GetDlgItem を使用してコントロールにアクセスした場合、コントロールは正しく機能しません。 代わりに、次のいずれかの方法を使用して、コントロールを表すオブジェクトを取得する必要があります。
メンバー変数の追加ウィザードを使用して、[制御変数] を選択し、コントロールの ID を選択します。 メンバー変数名を入力し、[コントロールの種類] としてコントロールのラッパー クラスを選択します。
または
ローカル変数とサブクラスをダイアログ項目として宣言します。 次のようなコードを挿入します (
CMyCtrl
はラッパー クラスであり、IDC_MYCTRL1 はコントロールの ID です)。CCirc myCirc; myCirc.SubclassDlgItem(IDC_CIRCCTRL2, this); // ... use myCirc ... myCirc.UnsubclassWindow();