MFC ActiveX コントロール : 高度なトピック
ここでは、ActiveX コントロールの開発に関する以下のような高度なトピックについて説明します。 このようなコントロールを次に示します。
ActiveX コントロールにおけるデータベース クラスの使用
パラメーター化したプロパティの実装
ActiveX コントロールにおけるエラー処理
コントロールにおける特殊なキーの処理
実行時に表示されないダイアログ コントロールへのアクセス
ActiveX コントロールにおけるデータベース クラスの使用
ActiveX コントロールのクラスはクラス ライブラリに含まれているため、MFC データベース クラスを使う ActiveX コントロールを開発する際の手順や規則は、標準の MFC アプリケーションでデータベース クラスを使う場合と同様です。
MFC データベース クラスの概要については、「MFC データベース クラス (ODBC と DAO)」を参照してください。 MFC ODBC クラスと MFC DAO クラスの両方の紹介と、それぞれの詳しい情報の参照先があります。
注意
Visual C++ .NET では、Visual C++ 開発環境およびウィザードでは DAO はサポートされなくなりました (DAO クラスは含まれているので、このクラスを使うことはできます)。 新規プロジェクトの作成には、OLE DB テンプレートまたは ODBC および MFC の使用をお勧めします。 DAO は、既存のアプリケーションを保守するためだけに使用してください。
パラメーター化したプロパティの実装
パラメーター化したプロパティ (プロパティ配列とも呼ばれる) を使うと、同じ型の値の集合をコントロールの 1 つのプロパティとして公開できます。 たとえば、配列やディクショナリをプロパティとして公開できます。 Visual Basic でパラメーター化したプロパティにアクセスするには、配列表記を使用します。
x = o.Array(2, 3) ' gets element of 2D array
o.Array(2, 3) = 7 ' sets element of 2D array
パラメーター化したプロパティを実装するには、プロパティ追加 ウィザードを使用します。 プロパティ追加 ウィザードは、1 組の Get/Set 関数を追加してプロパティを実装します。これにより、コントロールのユーザーは、上の形式を使うか標準の方法を使ってプロパティにアクセスできるようになります。
パラメーター化したプロパティでは、メソッドやプロパティと同じように、使用できるパラメーターの数が制限されています。 パラメーター化したプロパティで使用できるのは 15 までです (1 つはプロパティ値の格納のために予約済み)。
次の手順では、整数の 2 次元配列としてアクセスできる、Array という名前のパラメーター化したプロパティを追加します。
プロパティ追加 ウィザードを使ってパラメーター化したプロパティを追加するには
コントロールのプロジェクトを読み込みます。
[クラス ビュー] ウィンドウで、コントロールのライブラリ ノードを展開します。
コントロールのインターフェイス ノード (ライブラリ ノードの 2 番目のノード) を右クリックし、ショートカット メニューを開きます。
ショートカット メニューの [追加] をクリックし、[プロパティの追加] をクリックします。
[プロパティ名] ボックスに「Array」と入力します。
[プロパティの種類] ボックスで、[SHORT] を選択します。
実装型として、[Get/Set メソッド] をクリックします。
[Get 関数]ボックスと [Set 関数] ボックスに、使用する Get 関数と Set 関数の一意の名前を入力するか、既定の名前を使用します。
[パラメーター名] ボックスと [パラメーターの型] ボックスを使って、row という short 型のパラメーターを追加します。
column という 2 番目のパラメーター (short 型) を追加します。
[完了] をクリックします。
プロパティ追加ウィザードによる変更
カスタム プロパティを追加すると、プロパティ追加 ウィザードによって、コントロール クラスのヘッダー (.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 関数には、通常、プロパティの変更の前または後に実行するコードを含めます。
パラメーター化したプロパティの値を格納する 2 次元配列のメンバー変数 (short 型) をコントロール クラスで宣言すると、このプロパティを有効に利用できるようになります。 これにより、パラメーターによって指定された行と列に格納されている値を返すように Get 関数を変更し、行と列のパラメーターによって参照されている値を更新するように Set 関数を変更できます。
ActiveX コントロールにおけるエラー処理
コントロールで発生したエラーをコントロール コンテナーに通知する必要がある場合があります。 エラーを通知する方法は 2 つあり、エラーが発生した状況に応じて使い分けます。 プロパティの Get 関数または Set 関数の中でエラーが発生した場合や、OLE オートメーション メソッドの実装内でエラーが発生した場合は、コントロールで COleControl::ThrowError を呼び出して、エラーが発生したことをコントロールのユーザーに知らせる必要があります。 これ以外の状況でエラーが発生した場合は、COleControl::FireError を呼び出して、Error ストック イベントを発生させます。
発生したエラーの種類を示すには、コントロールから ThrowError または FireError にエラー コードを渡す必要があります。 エラー コードとは、32 ビットの値を持つ OLE ステータス コードです。 OLECTL.H ヘッダー ファイルに定義されている標準のエラー コードの中に該当するものがある場合は、それを選択します。 次のようなエラー コードが定義されています。
ActiveX コントロールのエラー コード
Error |
説明 |
---|---|
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 キーが押されたら新しい行を挿入したり、方向キーが押されたらエディット コントロール間を移動したりする場合などです。
ActiveX コントロールの基本クラスが COleControl の場合は、CWnd::PreTranslateMessage をオーバーライドすると、コンテナーより先にメッセージを処理できます。 この方法を使うときには、PreTranslateMessage のオーバーライドでメッセージを処理する場合に常に TRUE を返します。
方向キーに関するメッセージを処理するコードは、たとえば次のようになります。
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();