Aracılığıyla paylaş


Olay işleme com

com olay işleme kullanarak bir olay kaynağı ve olay alıcı ayarlamak OLAY_KAYNAĞI ve event_receiver sırasıyla belirten öznitelikleri type=com.Bu öznitelikler, uygun özel kodu, gönderme ve olayları yangın ve com bağlantı noktaları üzerinden olayları işlemek için uygulanmadan sınıflarına izin verecek şekilde çift arabirim ekleme.

Olayları bildirme

Bir olay kaynağı sınıfı kullanmak __event bu arabirimin yöntem olayları bildirmek için bir arabirim bildirimi anahtar sözcüğü.Arabirim yöntemleri çağırdığınızda, bu arabirimin olaylarý tetiklenir.Olay arabirimlerindeki yöntemler, sıfır veya daha fazla parametre olabilir (tüm olacağı , parametreleri).Dönüş türü void veya herhangi bir tam sayı türü olabilir.

Olay İşleyicileri Tanımlama

Bir olay alıcı sınıfı yöntemleri ele olay uyan (dönüş türleri arama kuralları ve bağımsız değişkenler) imzaları ile olay işleyicileri tanımlayın.com olayları için arama kuralları eşleşmesi gerekmez; Bkz: Düzeni bağımlı com olayları altındaki ayrıntılar için.

Olayları için olay işleyicileri takma

Ayrıca bir olay alıcı sınıfı, içsel işlevini kullanın __hook olayları olay işleyicileri ile ilişkilendirmek ve __unhook olay işleyicileri olay DISSOCIATE için.Çeşitli olaylar için bir olay işleyicisi veya birden çok olay işleyicisini olaya bağlayın.

[!NOT]

Genellikle, bir com olay alıcı olay kaynağı arabirim tanımları erişmek izin vermek için iki tekniği vardır.İlki, aşağıda gösterildiği gibi ortak bir üstbilgi dosyası paylaşmaktır.İkinci kullanmaktır #import ile embedded_idl olay kaynağı türü kitaplığı korunur özniteliği tarafından üretilen koduyla .tlh dosyasına yazılır böylece niteleyici, Al.

Olay tetikleme

Bir olayı, sadece bir yöntem ile bildirilen arabiriminde çağrısı __event olay kaynağı class anahtar sözcüğü.İşleyicileri olay API'lerin, işleyicileri denir.

hdcxwbd5.collapse_all(tr-tr,VS.110).gifcom Olay kodu

Aşağıdaki örnek, bir com sýnýfý olarak bir olay tetikleyin gösterilmiştir.Derleyip örneği çalıştırmak için koddaki açıklamalara başvurun.

// evh_server.h
#pragma once

[ dual, uuid("00000000-0000-0000-0000-000000000001") ]
__interface IEvents {
   [id(1)] HRESULT MyEvent([in] int value);
};

[ dual, uuid("00000000-0000-0000-0000-000000000002") ]
__interface IEventSource {
   [id(1)] HRESULT FireEvent();
};

class DECLSPEC_UUID("530DF3AD-6936-3214-A83B-27B63C7997C4") CSource;

Ve sonra server:

// evh_server.cpp
// compile with: /LD
// post-build command: Regsvr32.exe /s evh_server.dll
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include "evh_server.h"

[ module(dll, name="EventSource", uuid="6E46B59E-89C3-4c15-A6D8-B8A1CEC98830") ];

[coclass, event_source(com), uuid("530DF3AD-6936-3214-A83B-27B63C7997C4")]
class CSource : public IEventSource {
public:
   __event __interface IEvents; 

   HRESULT FireEvent() {
      __raise MyEvent(123);
      return S_OK;
   }
};

Ve sonra istemci:

// evh_client.cpp
// compile with: /link /OPT:NOREF
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <stdio.h>
#include "evh_server.h"

[ module(name="EventReceiver") ];

[ event_receiver(com) ]
class CReceiver {
public:
   HRESULT MyHandler1(int nValue) {
      printf_s("MyHandler1 was called with value %d.\n", nValue);
      return S_OK;
   }

   HRESULT MyHandler2(int nValue) {
      printf_s("MyHandler2 was called with value %d.\n", nValue);
      return S_OK;
   }

   void HookEvent(IEventSource* pSource) {
      __hook(&IEvents::MyEvent, pSource, &CReceiver::MyHandler1);
      __hook(&IEvents::MyEvent, pSource, &CReceiver::MyHandler2);
   }

   void UnhookEvent(IEventSource* pSource) {
      __unhook(&IEvents::MyEvent, pSource, &CReceiver::MyHandler1);
      __unhook(&IEvents::MyEvent, pSource, &CReceiver::MyHandler2);
   }
};

int main() {
   // Create COM object
   CoInitialize(NULL);
   {
      IEventSource* pSource = 0;
      HRESULT hr = CoCreateInstance(__uuidof(CSource), NULL,         CLSCTX_ALL, __uuidof(IEventSource), (void **) &pSource);
      if (FAILED(hr)) {
         return -1;
      }

      // Create receiver and fire event
      CReceiver receiver;
      receiver.HookEvent(pSource);
      pSource->FireEvent();
      receiver.UnhookEvent(pSource);
   }
   CoUninitialize();
   return 0;
}

hdcxwbd5.collapse_all(tr-tr,VS.110).gifÇıktı

MyHandler1 was called with value 123.
MyHandler2 was called with value 123.

Düzen bağımlı com olayları

Düzen bağımlılık com programlaması için yalnızca bir sorun var.Doğal ve yönetilen olay işleme işleyicilerinin imzaları (dönüş türü, çağırma kuralı ve bağımsız değişkenler) etkinliklerini eşleşmesi gerekir, ancak işleyicisi adları etkinliklerini eşleşmesi gerekmez.

Ayarladığınız zaman ancak com olay İşlemede, layout_dependent parametresi event_receiver için doğru, adı ve imzası eşleştirme koşulları uygulanır.Alıcı adlarını ve imzalar API'lerin olayların tam olarak eşleşmesi durumunda bu adları ve işleyicilerinin imzaları anlamına gelir.

Zaman layout_dependent ayarlamak yanlış, çağırma kuralı ve depolama sınıfı (sanal, statik ve böyle devam eder) karışık ve Açmadığınızda arasında eşleşen olay yöntemi ve hooking yöntemleri (kendi temsilciler).İçin biraz daha verimli layout_dependent=doğru.

Örneğin, varsayalım IEventSource aşağıdaki yöntemleri tanımlanır:

[id(1)] HRESULT MyEvent1([in] int value);
[id(2)] HRESULT MyEvent2([in] int value);

Aşağıdaki formu olay kaynağı olduğunu varsayalım:

[coclass, event_source(com)]
class CSource : public IEventSource {
public:
   __event __interface IEvents;

   HRESULT FireEvent() {
      MyEvent1(123);
      MyEvent2(123);
      return S_OK;
   }
};

Daha sonra herhangi bir işleyici olay alıcısında API'lerin bir yönteme IEventSource adı ve imzası gibi eşleşmesi gerekir:

[coclass, event_receiver(com, true)]
class CReceiver {
public:
   HRESULT MyEvent1(int nValue) {  // name and signature matches MyEvent1
      ...
   }
   HRESULT MyEvent2(E c, char* pc) {  // signature doesn't match MyEvent2
      ...
   }
   HRESULT MyHandler1(int nValue) {  // name doesn't match MyEvent1 (or 2)
      ...
   }
   void HookEvent(IEventSource* pSource) {
      __hook(IFace, pSource);  // Hooks up all name-matched events 
                               // under layout_dependent = true
      __hook(&IFace::MyEvent1, pSource, &CReceive::MyEvent1);   // valid
      __hook(&IFace::MyEvent2, pSource, &CSink::MyEvent2);   // not valid
      __hook(&IFace::MyEvent1, pSource, &CSink:: MyHandler1); // not valid
   }
};

Ayrıca bkz.

Başvuru

Olay işleme