Обработка событий в неуправляемом C++Event handling in native C++

При обработке событий в собственном C++ вы настраиваете источник события и приемник событий, используя атрибуты event_source и event_receiver соответственно, указывая type = native .In native C++ event handling, you set up an event source and event receiver using the event_source and event_receiver attributes, respectively, specifying type=native. Эти атрибуты позволяют классам, к которым они применяются, вызывать события и управлять событиями в собственном контексте, не являющемся контекстом COM.These attributes allow the classes they're applied on to fire events and handle events in a native, non-COM context.

Примечание

Атрибуты событий в машинном коде C++ несовместимы со стандартным C++.Event attributes in native C++ are incompatible with Standard C++. Они не компилируются при указании /permissive- режима соответствия.They don't compile when you specify /permissive- conformance mode.

Объявление событийDeclaring events

В классе источника событий используйте __event ключевое слово в объявлении метода, чтобы объявить метод как событие.In an event source class, use the __event keyword on a method declaration to declare the method as an event. Обязательно объявите метод, но не определяйте его.Make sure to declare the method, but don't define it. В этом случае возникает ошибка компилятора, так как компилятор определяет метод неявно, когда он преобразуется в событие.If you do, it generates a compiler error, because the compiler defines the method implicitly when it's made into an event. Собственные события могут быть методами с нулевым или большим количеством параметров.Native events can be methods with zero or more parameters. Возвращаемым типом может быть void или любой целочисленный тип.The return type can be void or any integral type.

Определение обработчиков событийDefining event handlers

В классе приемника событий определяются обработчики событий.In an event receiver class, you define event handlers. Обработчики событий — это методы с сигнатурами (возвращаемыми типами, соглашениями о вызовах и аргументами), которые соответствуют событию, которое они будут обработаны.Event handlers are methods with signatures (return types, calling conventions, and arguments) that match the event that they'll handle.

Подключение обработчиков событий к событиямHooking event handlers to events

Кроме того, в классе приемника событий используется встроенная функция __hook для связывания событий с обработчиками событий и для разрыва __unhook связи между событиями из обработчиков событий.Also in an event receiver class, you use the intrinsic function __hook to associate events with event handlers and __unhook to disassociate events from event handlers. Можно прикрепить несколько событий к обработчику событий либо несколько обработчиков событий к одному событию.You can hook several events to an event handler, or several event handlers to an event.

События, вызывающие срабатываниеFiring events

Чтобы запустить событие, вызовите метод, объявленный как событие в классе источника событий.To fire an event, call the method declared as an event in the event source class. Если обработчики прикреплены к событию, они будут вызваны.If handlers have been hooked to the event, the handlers will be called.

Код события машинного кода C++Native C++ event code

В следующем примере демонстрируется порождение события в собственном коде C++.The following example shows how to fire an event in native C++. Для компиляции и выполнения примера см. комментарии в коде.To compile and run the example, refer to the comments in the code. Чтобы создать код в интегрированной среде разработки Visual Studio, убедитесь, что /permissive- параметр отключен.To build the code in the Visual Studio IDE, verify that the /permissive- option is turned off.

ПримерExample

КодCode

// evh_native.cpp
// compile by using: cl /EHsc /W3 evh_native.cpp
#include <stdio.h>

[event_source(native)]
class CSource {
public:
   __event void MyEvent(int nValue);
};

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

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

   void hookEvent(CSource* pSource) {
      __hook(&CSource::MyEvent, pSource, &CReceiver::MyHandler1);
      __hook(&CSource::MyEvent, pSource, &CReceiver::MyHandler2);
   }

   void unhookEvent(CSource* pSource) {
      __unhook(&CSource::MyEvent, pSource, &CReceiver::MyHandler1);
      __unhook(&CSource::MyEvent, pSource, &CReceiver::MyHandler2);
   }
};

int main() {
   CSource source;
   CReceiver receiver;

   receiver.hookEvent(&source);
   __raise source.MyEvent(123);
   receiver.unhookEvent(&source);
}

ВыводOutput

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

См. такжеSee also

Обработка событийEvent handling