イベントの追加 (ATL チュートリアル、パート 5)
この手順では、ClickIn
イベントと ClickOut
イベントを ATL コントロールに追加します。 ユーザーが多角形の内側をクリックすると ClickIn
イベントが発生し、ユーザーが外側をクリックすると ClickOut
イベントが発生するようにします。 イベントを追加するタスクは次のとおりです。
ClickIn
メソッドとClickOut
メソッドの追加タイプ ライブラリの生成
接続ポイント インターフェイスの実装
ClickIn メソッドと ClickOut メソッドの追加
手順 2 で ATL コントロールを作成したときに、[接続ポイント] チェック ボックスをオンにしました。 これにより、Polygon.idl ファイルに _IPolyCtlEvents
インターフェイスが作成されました。 インターフェイス名はアンダースコアで始まります。 これは、インターフェイスが内部インターフェイスであることを示すための規則です。 したがって、COM オブジェクトを参照できるプログラムでは、インターフェイスをユーザーに表示しないことを選択できます。 また、[接続ポイント] をオンにすることで、_IPolyCtlEvents
が既定のソース インターフェイスであることを示す次の行が Polygon.idl ファイルに追加されました。
[default, source] dispinterface _IPolyCtlEvents;
source 属性は、コントロールが通知のソースであることを示しているので、コンテナーでこのインターフェイスが呼び出されます。
ここで、ClickIn
メソッドと ClickOut
メソッドを _IPolyCtlEvents
インターフェイスに追加します。
ClickIn メソッドと ClickOut メソッドを追加するには
ソリューション エクスプローラーで Polygon.idl を開き、PolygonLib ライブラリの
dispInterface_IPolyCtlEvents
宣言内のmethods:
の下に次のコードを追加します。[id(1), helpstring("method ClickIn")] void ClickIn([in] LONG x,[in] LONG y); [id(2), helpstring("method ClickOut")] void ClickOut([in] LONG x,[in] LONG y);
ClickIn
メソッドと ClickOut
メソッドは、クリックされた点の X 座標と Y 座標をパラメーターとして取得します。
タイプ ライブラリの生成
この時点で、タイプ ライブラリを生成します。これは、プロジェクトでこのライブラリを使用して、コントロールに対して接続ポイント インターフェイスと接続ポイント コンテナー インターフェイスを作成するのに必要な情報を取得するためです。
タイプ ライブラリを生成するには
プロジェクトのリビルドします。
または
ソリューション エクスプローラーで Polygon.idl ファイルを右クリックし、ショートカット メニューの [コンパイル] をクリックします。
これにより、タイプ ライブラリである Polygon.tlb ファイルが作成されます。 Polygon.tlb ファイルはバイナリ ファイルであり、直接表示または編集できないため、ソリューション エクスプローラーからは参照できません。
接続ポイント インターフェイスの実装
コントロールの接続ポイント インターフェイスと接続ポイント コンテナー インターフェイスを実装します。 COM では、接続ポイントのメカニズムによってイベントが実装されます。 COM オブジェクトからイベントを受信するために、コンテナーでは、COM オブジェクトによって実装される接続ポイントへのアドバイザリ コネクションが確立されます。 COM オブジェクトは複数の接続ポイントを持つことができるため、COM オブジェクトでは接続ポイント コンテナー インターフェイスも実装されます。 コンテナーでは、このインターフェイスを使用して、サポートされている接続ポイントを特定できます。
接続ポイントを実装するインターフェイスは IConnectionPoint
と呼ばれ、接続ポイント コンテナーを実装するインターフェイスは IConnectionPointContainer
と呼ばれます。
IConnectionPoint
を実装するには、接続ポイントの実装ウィザードを使用します。 このウィザードでは、タイプ ライブラリを読み取り、発生する可能性のある各イベントに対して関数を実装することで、IConnectionPoint
インターフェイスを生成します。
接続ポイントを実装するには
ソリューション エクスプローラーで _IPolyCtlEvents_CP.h を開き、
CProxy_IPolyCtlEvents
クラスのpublic:
ステートメントの下に次のコードを追加します。VOID Fire_ClickIn(LONG x, LONG y) { T* pT = static_cast<T*>(this); int nConnectionIndex; CComVariant* pvars = new CComVariant[2]; int nConnections = m_vec.GetSize(); for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++) { pT->Lock(); CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex); pT->Unlock(); IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p); if (pDispatch != NULL) { pvars[1].vt = VT_I4; pvars[1].lVal = x; pvars[0].vt = VT_I4; pvars[0].lVal = y; DISPPARAMS disp = { pvars, NULL, 2, 0 }; pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL); } } delete[] pvars; } VOID Fire_ClickOut(LONG x, LONG y) { T* pT = static_cast<T*>(this); int nConnectionIndex; CComVariant* pvars = new CComVariant[2]; int nConnections = m_vec.GetSize(); for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++) { pT->Lock(); CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex); pT->Unlock(); IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p); if (pDispatch != NULL) { pvars[1].vt = VT_I4; pvars[1].lVal = x; pvars[0].vt = VT_I4; pvars[0].lVal = y; DISPPARAMS disp = { pvars, NULL, 2, 0 }; pDispatch->Invoke(0x2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL); } } delete[] pvars; }
このファイルには、IConnectionPointImpl
から派生した CProxy_IPolyCtlEvents
というクラスが含まれていることがわかります。 これで _IPolyCtlEvents_CP.h には、2 つのメソッド Fire_ClickIn
と Fire_ClickOut
が定義されます。これらは 2 つの座標パラメーターを受け取ります。 コントロールからイベントを発生させるには、これらのメソッドを呼び出します。
[接続ポイント] オプションを選択してコントロールを作成することで、_IPolyCtlEvents_CP.h ファイルが自動的に生成されました。 また、適切なエントリを COM マップに追加することで、自動的に CProxy_PolyEvents
と IConnectionPointContainerImpl
がコントロールの複数の継承リストに追加され、IConnectionPointContainer
が公開されました。
イベントをサポートするコードの実装が完了しました。 ここで、適切な時点でイベントを発生させるコードをいくつか追加します。 ユーザーがコントロールでマウスの左ボタンをクリックすると、ClickIn
イベントまたは ClickOut
イベントが発生するようにします。 ユーザーがボタンをクリックしたことを認識できるように、WM_LBUTTONDOWN
メッセージのハンドラーを追加します。
WM_LBUTTONDOWN メッセージのハンドラーを追加するには
クラス ビューで
CPolyCtl
クラスを右クリックし、ショートカット メニューの [プロパティ] をクリックします。[プロパティ] ウィンドウで、[メッセージ] アイコンをクリックし、左側の一覧で
WM_LBUTTONDOWN
をクリックします。表示されるドロップダウン リストで、[<Add> OnLButtonDown] をクリックします。
OnLButtonDown
ハンドラーの宣言が PolyCtl.h に追加され、ハンドラーの実装が PolyCtl.cpp に追加されます。
次に、ハンドラーを変更します。
OnLButtonDown メソッドを変更するには
次のように、PolyCtl.cpp の
OnLButtonDown
メソッドで構成されるコードを変更します (ウィザードによって配置されたコードをすべて削除します)。LRESULT CPolyCtl::OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) { HRGN hRgn; WORD xPos = LOWORD(lParam); // horizontal position of cursor WORD yPos = HIWORD(lParam); // vertical position of cursor CalcPoints(m_rcPos); // Create a region from our list of points hRgn = CreatePolygonRgn(&m_arrPoint[0], m_nSides, WINDING); // If the clicked point is in our polygon then fire the ClickIn // event otherwise we fire the ClickOut event if (PtInRegion(hRgn, xPos, yPos)) Fire_ClickIn(xPos, yPos); else Fire_ClickOut(xPos, yPos); // Delete the region that we created DeleteObject(hRgn); return 0; }
このコードでは、OnDraw
関数で計算されたポイントを使用して、PtInRegion
の呼び出しによってユーザーのマウス クリックを検出する領域を作成します。
uMsg パラメーターは、処理される Windows メッセージの ID です。 これにより、一連のメッセージを処理する 1 つの関数を使用できます。 wParam パラメーターと lParam パラメーターは、処理されるメッセージの標準値です。 bHandled パラメーターを使用すると、関数によってメッセージが処理されたかどうかを指定できます。 既定でこの値は、関数によってメッセージが処理されたことを示す TRUE に設定されますが、FALSE に設定することもできます。 これにより、メッセージの送信先である別のメッセージ ハンドラー関数の検索が ATL によって続行されます。
コントロールのビルドとテスト
次に、イベントを試してみましょう。 コントロールをビルドし、ActiveX コントロール テスト コンテナーを再び開始します。 今回は、イベント ログ ウィンドウを表示します。 イベントを出力ウィンドウにルーティングするには、[オプション] メニューの [ログ] をクリックし、[出力ウィンドウにログを記録] を選択します。 コントロールを挿入し、ウィンドウ内をクリックしてみます。 塗りつぶされた多角形の内側をクリックすると ClickIn
が起動され、その外側をクリックすると ClickOut
が起動されます。
次に、プロパティ ページを追加します。
関連項目
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示