Přidání události (ATL – tutoriál, část 5)
V tomto kroku přidáte ClickIn
do ovládacího prvku ATL událost a ClickOut
událost. Událost se aktivuje ClickIn
, pokud uživatel klikne do mnohoúhelníku a aktivuje ClickOut
se, pokud uživatel klikne mimo. Úkoly, které chcete přidat událost, jsou následující:
Přidání metod
ClickIn
aClickOut
metodGenerování knihovny typů
Implementace rozhraní spojovacího bodu
Přidání metod ClickIn a ClickOut
Po vytvoření ovládacího prvku ATL v kroku 2 jste zaškrtnuli políčko Spojovací body . Tím se _IPolyCtlEvents
rozhraní vytvořilo v souboru Polygon.idl. Všimněte si, že název rozhraní začíná podtržítkem. Jedná se o konvenci, která označuje, že rozhraní je interní rozhraní. Programy, které umožňují procházet objekty MODELU COM, se proto nemohou rozhodnout, že se nezobrazí rozhraní pro uživatele. Všimněte si také, že při výběru spojovacích bodů se do souboru Polygon.idl přidal následující řádek, který označuje, že _IPolyCtlEvents
se jedná o výchozí zdrojové rozhraní:
[default, source] dispinterface _IPolyCtlEvents;
Zdrojový atribut označuje, že ovládací prvek je zdrojem oznámení, takže bude volat toto rozhraní v kontejneru.
Nyní přidejte do rozhraní metody ClickIn
a ClickOut
metody _IPolyCtlEvents
.
Přidání metod ClickIn a ClickOut
V Průzkumník řešení otevřete Polygon.idl a do deklarace knihovny PolygonLib přidejte následující kód
methods:
dispInterface_IPolyCtlEvents
:[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);
ClickOut
Metody ClickIn
přebírají souřadnice x a y klikaného bodu jako parametry.
Generování knihovny typů
Vygenerujte knihovnu typů v tomto okamžiku, protože projekt ji použije k získání informací, které potřebuje k vytvoření rozhraní spojovacího bodu a rozhraní kontejneru spojovacího bodu pro váš ovládací prvek.
Generování knihovny typů
Znovu sestavte projekt.
nebo
Klikněte pravým tlačítkem myši na soubor Polygon.idl v Průzkumník řešení a v místní nabídce klepněte na příkaz Zkompilovat.
Tím se vytvoří soubor Polygon.tlb, což je vaše knihovna typů. Soubor Polygon.tlb není z Průzkumník řešení viditelný, protože se jedná o binární soubor a nelze jej přímo zobrazit ani upravit.
Implementace rozhraní spojovacího bodu
Implementujte rozhraní spojovacího bodu a rozhraní kontejneru spojovacího bodu pro váš ovládací prvek. V modelu COM se události implementují prostřednictvím mechanismu spojovacích bodů. Pokud chcete přijímat události z objektu COM, kontejner vytvoří poradní připojení k spojovacímu bodu, který objekt COM implementuje. Protože objekt COM může mít více spojovacích bodů, objekt COM také implementuje rozhraní kontejneru spojovacího bodu. Prostřednictvím tohoto rozhraní může kontejner určit, které spojovací body jsou podporovány.
Rozhraní, které implementuje spojovací bod je volána IConnectionPoint
a rozhraní, které implementuje kontejner spojovacího bodu je volána IConnectionPointContainer
.
K implementaci IConnectionPoint
použijete Průvodce implementací spojovacího bodu. Tento průvodce vygeneruje IConnectionPoint
rozhraní načtením knihovny typů a implementací funkce pro každou událost, která se dá aktivovat.
Implementace spojovacích bodů
V Průzkumník řešení otevřete _IPolyCtlEvents_CP.h a do příkazu třídy
CProxy_IPolyCtlEvents
přidejte následující kódpublic:
: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; }
Uvidíte, že tento soubor má třídu, která je odvozena CProxy_IPolyCtlEvents
od IConnectionPointImpl
. _IPolyCtlEvents_CP.h nyní definuje dvě metody Fire_ClickIn
a Fire_ClickOut
, které přebírají dva parametry souřadnic. Tyto metody zavoláte, když chcete z ovládacího prvku aktivovat událost.
Vytvořením ovládacího prvku s vybranou možností Spojovací body se pro vás vygeneroval soubor _IPolyCtlEvents_CP.h. Přidala se také CProxy_PolyEvents
do seznamu dědičnosti vašeho ovládacího prvku a IConnectionPointContainerImpl
byla pro vás zpřístupněna IConnectionPointContainer
přidáním příslušných položek do mapy COM.
Dokončili jste implementaci kódu pro podporu událostí. Teď přidejte nějaký kód pro vyvolání událostí v příslušném okamžiku. Nezapomeňte, že když uživatel klikne na levé tlačítko myši v ovládacím prvku, aktivuje ClickIn
ClickOut
se událost. Pokud chcete zjistit, kdy uživatel klikne na tlačítko, přidejte obslužnou rutinu WM_LBUTTONDOWN
zprávy.
Přidání obslužné rutiny pro zprávu WM_LBUTTONDOWN
V zobrazení třídy klepněte pravým tlačítkem myši na
CPolyCtl
třídu a klepněte na příkaz Vlastnosti v místní nabídce.V okně Vlastnosti klikněte na ikonu Zprávy a potom klikněte
WM_LBUTTONDOWN
ze seznamu na levé straně.V rozevíracím seznamu, který se zobrazí, klikněte na <Přidat> OnLButtonDown. Deklarace
OnLButtonDown
obslužné rutiny bude přidána do PolyCtl.h a implementace obslužné rutiny bude přidána do PolyCtl.cpp.
Dále upravte obslužnou rutinu.
Úprava metody OnLButtonDown
Změňte kód, který se skládá z
OnLButtonDown
metody v PolyCtl.cpp (odstranění jakéhokoli kódu umístěného průvodcem), aby vypadal takto: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; }
Tento kód používá body počítané ve OnDraw
funkci k vytvoření oblasti, která zjistí kliknutí myší uživatele pomocí volání PtInRegion
.
Parametr uMsg je ID zpracovávané zprávy systému Windows. To vám umožní mít jednu funkci, která zpracovává rozsah zpráv. Parametry wParam a lParam jsou standardními hodnotami pro zpracovávanou zprávu. Parametr bHandled umožňuje určit, zda funkce zpracovávala zprávu, nebo ne. Ve výchozím nastavení je hodnota nastavena na HODNOTU TRUE, která označuje, že funkce zpracovávala zprávu, ale můžete ji nastavit na HODNOTU FALSE. To způsobí, že ATL bude pokračovat v hledání další funkce obslužné rutiny zprávy k odeslání zprávy.
Sestavení a testování ovládacího prvku
Teď si vyzkoušejte své události. Sestavte ovládací prvek a znovu spusťte testovací kontejner ovládacího prvku ActiveX. Tentokrát si prohlédněte okno protokolu událostí. Chcete-li směrovat události do okna výstupu, klepněte v nabídce Možnosti na příkaz Protokolování a vyberte možnost Protokol do výstupního okna. Vložte ovládací prvek a zkuste kliknout do okna. Všimněte si, že ClickIn
je aktivována, pokud kliknete do vyplněného mnohoúhelníku a ClickOut
aktivuje se, když kliknete mimo něj.
V dalším kroku přidáte stránku vlastností.