Aggiunta di un evento (Esercitazione di ATL, parte 5)
In questo passaggio si aggiungerà un ClickIn
oggetto e un ClickOut
evento al controllo ATL. Verrà generato l'evento ClickIn
se l'utente fa clic all'interno del poligono e verrà attivato ClickOut
se l'utente fa clic all'esterno. Le attività per aggiungere un evento sono le seguenti:
Aggiunta dei
ClickIn
metodi eClickOut
Generazione della libreria dei tipi
Implementazione delle interfacce del punto di connessione
Aggiunta dei metodi ClickIn e ClickOut
Dopo aver creato il controllo ATL nel passaggio 2, è stata selezionata la casella di controllo Punti di connessione. L'interfaccia _IPolyCtlEvents
è stata creata nel file Polygon.idl. Si noti che il nome dell'interfaccia inizia con un carattere di sottolineatura. Si tratta di una convenzione per indicare che l'interfaccia è un'interfaccia interna. Pertanto, i programmi che consentono di esplorare gli oggetti COM possono scegliere di non visualizzare l'interfaccia all'utente. Si noti anche che selezionando Punti di connessione è stata aggiunta la riga seguente nel file Polygon.idl per indicare che _IPolyCtlEvents
è l'interfaccia di origine predefinita:
[default, source] dispinterface _IPolyCtlEvents;
L'attributo di origine indica che il controllo è l'origine delle notifiche, quindi chiamerà questa interfaccia nel contenitore.
Aggiungere ora i ClickIn
metodi e ClickOut
all'interfaccia _IPolyCtlEvents
.
Per aggiungere i metodi ClickIn e ClickOut
In Esplora soluzioni aprire Polygon.idl e aggiungere il codice
methods:
seguente in nelladispInterface_IPolyCtlEvents
dichiarazione della libreria PolygonLib:[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);
I ClickIn
metodi e ClickOut
accettano le coordinate x e y del punto selezionato come parametri.
Generazione della libreria dei tipi
Generare la libreria dei tipi a questo punto, perché il progetto lo userà per ottenere le informazioni necessarie per costruire un'interfaccia del punto di connessione e un'interfaccia del contenitore del punto di connessione per il controllo.
Per generare la libreria dei tipi
Ricompilare il progetto.
oppure
Fare clic con il pulsante destro del mouse sul file Polygon.idl in Esplora soluzioni e scegliere Compila dal menu di scelta rapida.
Verrà creato il file Polygon.tlb, ovvero la libreria dei tipi. Il file Polygon.tlb non è visibile da Esplora soluzioni, perché è un file binario e non può essere visualizzato o modificato direttamente.
Implementazione delle interfacce del punto di connessione
Implementare un'interfaccia del punto di connessione e un'interfaccia del contenitore del punto di connessione per il controllo. In COM gli eventi vengono implementati tramite il meccanismo dei punti di connessione. Per ricevere eventi da un oggetto COM, un contenitore stabilisce una connessione consultiva al punto di connessione implementato dall'oggetto COM. Poiché un oggetto COM può avere più punti di connessione, l'oggetto COM implementa anche un'interfaccia contenitore del punto di connessione. Tramite questa interfaccia, il contenitore può determinare quali punti di connessione sono supportati.
L'interfaccia che implementa un punto di connessione è denominata IConnectionPoint
e l'interfaccia che implementa un contenitore di punti di connessione è denominata IConnectionPointContainer
.
Per implementare IConnectionPoint
, si userà la Procedura guidata Implementa punto di connessione. Questa procedura guidata genera l'interfaccia IConnectionPoint
leggendo la libreria dei tipi e implementando una funzione per ogni evento che può essere generato.
Per implementare i punti di connessione
In Esplora soluzioni aprire _IPolyCtlEvents_CP.h e aggiungere il codice seguente sotto l'istruzione
public:
nellaCProxy_IPolyCtlEvents
classe :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; }
Si noterà che questo file ha una classe denominata CProxy_IPolyCtlEvents
che deriva da IConnectionPointImpl
. _IPolyCtlEvents_CP.h definisce ora i due metodi Fire_ClickIn
e Fire_ClickOut
, che accettano i due parametri di coordinate. Questi metodi vengono chiamati quando si desidera generare un evento dal controllo.
Creando il controllo con l'opzione Punti di connessione selezionata, il file _IPolyCtlEvents_CP.h è stato generato automaticamente. Viene inoltre aggiunto CProxy_PolyEvents
e IConnectionPointContainerImpl
all'elenco di ereditarietà multipla del controllo ed esposto IConnectionPointContainer
aggiungendo voci appropriate alla mappa COM.
È stata completata l'implementazione del codice per supportare gli eventi. Aggiungere ora del codice per generare gli eventi nel momento appropriato. Tenere presente che si attiverà un ClickIn
evento o ClickOut
quando l'utente fa clic sul pulsante sinistro del mouse nel controllo. Per scoprire quando l'utente fa clic sul pulsante, aggiungere un gestore per il WM_LBUTTONDOWN
messaggio.
Per aggiungere un gestore per il messaggio di WM_LBUTTONDOWN
In Visualizzazione classi fare clic con il pulsante destro del mouse sulla
CPolyCtl
classe e scegliere Proprietà dal menu di scelta rapida.Nella finestra Proprietà fare clic sull'icona Messaggi e quindi fare clic
WM_LBUTTONDOWN
sull'elenco a sinistra.Nell'elenco a discesa visualizzato fare clic su <Aggiungi> OnLButtonDown. La
OnLButtonDown
dichiarazione del gestore verrà aggiunta a PolyCtl.h e l'implementazione del gestore verrà aggiunta a PolyCtl.cpp.
Modificare quindi il gestore.
Per modificare il metodo OnLButtonDown
Modificare il codice che comprende il
OnLButtonDown
metodo in PolyCtl.cpp (eliminando qualsiasi codice inserito dalla procedura guidata) in modo che sia simile al seguente: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; }
Questo codice usa i punti calcolati nella OnDraw
funzione per creare un'area che rileva i clic del mouse dell'utente con la chiamata a PtInRegion
.
Il parametro uMsg è l'ID del messaggio di Windows gestito. In questo modo è possibile avere una funzione che gestisce un intervallo di messaggi. I parametri wParam e lParam sono i valori standard per il messaggio gestito. Il parametro bHandled consente di specificare se la funzione ha gestito o meno il messaggio. Per impostazione predefinita, il valore è impostato su TRUE per indicare che la funzione ha gestito il messaggio, ma è possibile impostarla su FALSE. In questo modo ATL continuerà a cercare un'altra funzione del gestore di messaggi a cui inviare il messaggio.
Compilazione e test del controllo
Provare ora gli eventi. Compilare il controllo e avviare di nuovo il contenitore di test del controllo ActiveX. Questa volta, visualizzare la finestra del registro eventi. Per instradare gli eventi alla finestra di output, fare clic su Registrazione dal menu Opzioni e selezionare Registra nella finestra di output. Inserire il controllo e provare a fare clic nella finestra. Si noti che ClickIn
viene generato se si fa clic all'interno del poligono riempito e ClickOut
viene generato quando si fa clic all'esterno di esso.
Successivamente, si aggiungerà una pagina delle proprietà.
Tornare al passaggio 4 | al passaggio 6