手順 6: プロパティ ページの追加
更新 : 2007 年 11 月
プロパティ ページは個別の COM オブジェクトとして実装されるため、必要な場合に共有できます。この手順では、以下のタスクを実行してプロパティ ページをコントロールに追加します。
プロパティ ページ リソースの作成
プロパティ ページを作成および管理するコードの追加
コントロールへのプロパティ ページの追加
プロパティ ページ リソースの作成
コントロールにプロパティ ページを追加するには、クラスの追加ウィザードを使用します。
プロパティ ページを追加するには
ソリューション エクスプローラで、Polygon を右クリックします。
ショートカット メニューの [追加] をポイントし、[クラスの追加] をクリックします。
テンプレートの一覧で [ATL プロパティ ページ] を選択し、[追加] をクリックします。
ATL プロパティ ページ ウィザードが表示されたら、[短い名前] に「PolyProp」という名前を入力します。
[文字列] をクリックして [文字列] ページを開き、[タイトル] に「&Polygon」と入力します。
プロパティ ページの [タイトル] は、そのページのタブに表示される文字列です。[ドキュメント文字列] は、プロパティ フレームがステータス ラインやツール ヒントに表示する説明です。現在、標準的なプロパティ フレームではこの文字列は使用されないため、既定の内容のままにできます。ヘルプ ファイルはここでは生成しないため、[ヘルプ ファイル] ボックスのエントリは消去します。
[完了] をクリックすると、プロパティ ページ オブジェクトが作成されます。
次の 3 つのファイルが作成されます。
ファイル |
説明 |
---|---|
PolyProp.h |
プロパティ ページを実装する CPolyProp という C++ クラスが含まれています。 |
PolyProp.cpp |
PolyProp.h ファイルをインクルードしています。 |
PolyProp.rgs |
プロパティ ページ オブジェクトを登録するレジストリ スクリプトです。 |
コードも次のように変更されます。
Polygon.cpp のオブジェクト エントリ マップに新しいプロパティ ページが追加されます。
Polygon.idl ファイルに PolyProp クラスが追加されます。
プロジェクト リソースに PolyProp.rgs という新しいレジストリ スクリプト ファイルが追加されます。
プロパティ ページのプロジェクト リソースにダイアログ ボックス テンプレートが追加されます。
指定したプロパティ文字列がリソース ストリング テーブルに追加されます。
ここで、プロパティ ページに表示するフィールドを追加します。
プロパティ ページにフィールドを追加するには
ソリューション エクスプローラで、Polygon.rc リソース ファイルをダブルクリックします。リソース ビューが表示されます。
リソース ビューで、[Dialog] ノードを展開し、[IDD_POLYPROP] をダブルクリックします。表示されるダイアログ ボックスには、コントロールの挿入を指示するラベルだけが表示されています。
そのラベルを選択し、[プロパティ] ウィンドウの [Caption] のテキストを変更し、ラベル ボックスのサイズを変更して、Sides: を読み取るようにラベルを変更します。
エディット コントロールをツールボックスからラベルの右側にドラッグします。
最後に、[プロパティ] ウィンドウを使用して、エディット コントロールの [ID] を IDC_SIDES に変更します。
これで、プロパティ ページ リソースの作成プロセスが完了しました。
プロパティ ページを作成および管理するコードの追加
プロパティ ページ リソースの作成が完了したので、次に実装コードを作成する必要があります。
まず、CPolyProp クラスを変更して、[適用] ボタンが押されたときにオブジェクトの辺の数を設定するようにします。
Apply 関数を変更して辺の数を設定するには
PolyProp.h の Apply 関数を次のように変更します。
STDMETHOD(Apply)(void) { USES_CONVERSION; ATLTRACE(_T("CPolyProp::Apply\n")); for (UINT i = 0; i < m_nObjects; i++) { CComQIPtr<IPolyCtl, &IID_IPolyCtl> pPoly(m_ppUnk[i]); short nSides = (short)GetDlgItemInt(IDC_SIDES); if FAILED(pPoly->put_Sides(nSides)) { CComPtr<IErrorInfo> pError; CComBSTR strError; GetErrorInfo(0, &pError); pError->GetDescription(&strError); MessageBox(OLE2T(strError), _T("Error"), MB_ICONEXCLAMATION); return E_FAIL; } } m_bDirty = FALSE; return S_OK; }
プロパティ ページに同時に複数のクライアントが接続することもあるため、Apply 関数でループ処理を行い、クライアントごとに put_Sides を呼び出して、エディット ボックスから取得された値を設定します。コードで CComQIPtr クラスを使用していますが、このクラスは各オブジェクトで QueryInterface を実行し、m_ppUnk 配列に格納されている IUnknown インターフェイスから IPolyCtl インターフェイスを取得します。
コードは、次に Sides プロパティの設定が実際に機能するかどうかを調べます。機能しない場合は、IErrorInfo インターフェイスから取得したエラーの詳細をメッセージ ボックスに表示します。通常は、コンテナがオブジェクトに ISupportErrorInfo インターフェイスを要求します。このとき、オブジェクトが設定エラー情報をサポートしているかどうかを調べるために、まず InterfaceSupportsErrorInfo を呼び出します。このタスクは省略することもできます。
CComPtr は参照カウントを自動的に処理するので、インターフェイスに対して Release を呼び出す必要はありません。CComBSTR は BSTR を適切に処理するので、最後に SysFreeString を呼び出す必要はありません。さらに、各種の文字列変換クラスを使用して、必要に応じて BSTR を変換できます。関数の最初に USES_CONVERSION マクロがあるのはこのためです。
また、[適用] ボタンを有効にするために、プロパティ ページのダーティ フラグを設定する必要があります。ユーザーが [サイド] ボックスの値を変更したときに、このフラグを有効にします。
[適用] ボタンを処理するには
[クラス ビュー] で CPolyProp を右クリックし、ショートカット メニューの [プロパティ] をクリックします。
[プロパティ] ウィンドウの [イベント] アイコンをクリックします。
イベント リストの [IDC_SIDES] ノードを展開します。
[EN_CHANGE] を選択し、右側のドロップダウン メニューで [<追加> OnEnChangeSides] をクリックします。OnEnChangeSides ハンドラの宣言が Polyprop.h に追加され、ハンドラの実装が Polyprop.cpp に追加されます。
次に、ハンドラを変更します。
OnEnChangeSides メソッドを変更するには
Polyprop.cpp の次のコードを OnEnChangeSides メソッドに追加します。ウィザードによって挿入されたコードはすべて削除してください。
LRESULT CPolyProp::OnEnChangeSides(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { SetDirty(TRUE); return 0; }
OnEnChangeSides は、WM_COMMAND メッセージが IDC_SIDES コントロールの EN_CHANGE 通知と共に送られたときに呼び出されます。OnEnChangeSides は SetDirty を呼び出して TRUE を渡し、プロパティ ページに変更が加えられているため [適用] ボタンを有効にする必要があることを知らせます。
コントロールへのプロパティ ページの追加
プロジェクト内に複数のコントロールが存在することがあるため、クラスの追加ウィザードおよび ATL プロパティ ページ ウィザードでは、プロパティ ページは自動的にはコントロールに追加されません。コントロールのプロパティ マップにエントリを追加する必要があります。
プロパティ ページを追加するには
PolyCtl.h を開き、プロパティ マップに次の行を追加します。
PROP_ENTRY_TYPE("Sides", 1, CLSID_PolyProp, VT_INT)
コントロールのプロパティ マップは、次のようになります。
BEGIN_PROP_MAP(CPolyCtl)
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
#ifndef _WIN32_WCE
PROP_ENTRY_TYPE("FillColor", DISPID_FILLCOLOR, CLSID_StockColorPage, VT_UI4)
#endif
PROP_ENTRY_TYPE("Sides", 1, CLSID_PolyProp, VT_INT)
// Example entries
// PROP_ENTRY("Property Description", dispid, clsid)
// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()
プロパティ ページの CLSID を持つ PROP_PAGE マクロを追加することもできますが、ここに示すように PROP_ENTRY マクロを使用すると、コントロールを保存するときに Sides プロパティの値も保存されます。
マクロに渡す 3 つのパラメータは、プロパティの説明、プロパティの DISPID、およびプロパティの存在するプロパティ ページの CLSID です。このマクロは、たとえば、コントロールを Visual Basic に読み込んで、デザイン時に Sides の数を設定する場合に便利です。Sides の数が保存されるため、Visual Basic プロジェクトを再読み込みしたときに、Sides の数が復元されます。
コントロールのビルドと動作確認
ここで、コントロールをビルドし、ActiveX コントロール テスト コンテナに挿入します。テスト コンテナで、[編集] メニューの [PolyCtl Class オブジェクト] をクリックします。プロパティ ページが表示されたら、[多角形 (P)] タブをクリックします。
最初は、[適用] ボタンが無効になっています。[サイド] ボックスへの値の入力を始めると、[適用] ボタンが有効になります。値の入力が終了したら、[適用] ボタンをクリックします。コントロールの表示が変わり、[適用] ボタンは再び無効になります。無効な値の入力を試してください。put_Sides 関数で設定したエラーの詳細を示すメッセージ ボックスが表示されます。
次の手順では、コントロールを Web ページに配置します。