演示如何使用Windows 运行时 C++ 模板库 (WRL)创建基本Windows 运行时 组件。 结果,当第,组件添加两个数字并引发事件。 此文档还会演示如何引发事件,以及如何使用来自使用 JavaScript 的 Windows 应用商店应用的组件。
系统必备
使用的 Windows 运行时体验。
与 COM 的体验。
创建将两个数相加的基本的 Windows 运行时 组件。
在 Visual Studio 中,创建 WRLClassLibrary 项目。Visual C++ WRL 类库项目模板 文档描述如何下载此模板。 将项目命名为 Contoso。
在 Contoso.cpp 和 Contoso.idl,用“计算器”替换“WinRTClass”的所有实例。
在 Contoso.idl,将 Add 方法添加到 ICalculator 接口。
HRESULT Add([in] int a, [in] int b, [out, retval] int* value);
将 Add 方法添加到Calculator类的 public 节中。
HRESULT __stdcall Add(_In_ int a, _In_ int b, _Out_ int* value) { if (value == nullptr) { return E_POINTER; } *value = a + b; return S_OK; }
重要
由于您创建 COM 组件,确保使用 __stdcall 调用约定。
建议您改用 _Out_ 和其他源代码注释语言 (SAL) 注释说明如何使用函数参数。 SAL 注释还描述返回值。 SAL 注释以 C/C++ 代码分析工具 使用发现可能存在的缺陷的 C# 和 C++ 源代码。 工具报告的常见编码错误包括缓冲区溢出、内存未初始化、null 指针取消引用以及内存和资源泄漏。
使用 JavaScript 从使用的 Windows 应用商店 应用的组件
在 Visual Studio 中,添加新 JavaScript 空白应用程序 项目添加到 Contoso 解决方案中。 将该项目命名为 CalculatorJS。
在CalculatorJS 测试项目中,添加对所测试 Contoso 项目的引用。
在 default.html,请使用这些 UI 元素替换 body 部分:
<div> <input id="a" /> <input id="b" /> <p id="result">Result:</p> <button onclick="Add()">Add</button> </div>
在 default.js,请实现 OnClick 函数。
function Add() { "use strict"; var calculator = new Contoso.Calculator(); var a = document.getElementById("a"); var b = document.getElementById("b"); document.getElementById("result").innerHTML = "Result: " + calculator.add(a.value, b.value); }
备注
在 JavaScript,方法名称的首字母小写更改为与标准命名约定。
添加该事件触发,当一个质数计算
在 Contoso.idl,在 ICalculator的声明之前,请定义 PrimeNumberEvent,委托类型,提供 int 参数。
[uuid(3FBED04F-EFA7-4D92-B04D-59BD8B1B055E), version(COMPONENT_VERSION)] delegate HRESULT PrimeNumberEvent(int primeNumber);
当使用 delegate 关键字时,MIDL 编译器创建一个包含 Invoke 方法与委托签名的接口。 在此示例中,生成的文件 Contoso_h.h 定义 IPrimeNumberEvent 接口,此过程稍后使用。
MIDL_INTERFACE("3FBED04F-EFA7-4D92-B04D-59BD8B1B055E") IPrimeNumberEvent : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE Invoke( int primeNumber) = 0; };
在 ICalculator 接口,请定义 PrimeNumberFound 事件。 eventadd 和 eventremove 特性指定 ICalculator 接口的使用者可以订阅以及从此事件取消订阅。
[eventadd] HRESULT PrimeNumberFound( [in] PrimeNumberEvent* eventHandler, [out, retval] EventRegistrationToken* eventCookie); [eventremove] HRESULT PrimeNumberFound( [in] EventRegistrationToken eventCookie);
在 Contoso.cpp,添加 private Microsoft::WRL::EventSource 成员变量管理事件订阅方和调用事件处理程序。
EventSource<IPrimeNumberEvent> m_events;
在 Contoso.cpp 中,执行add_PrimeNumberFound、 remove_PrimeNumberFound和 方法。
HRESULT __stdcall add_PrimeNumberFound(_In_ IPrimeNumberEvent* event, _Out_ EventRegistrationToken* eventCookie) { return m_events.Add(event, eventCookie); } HRESULT __stdcall remove_PrimeNumberFound(_In_ EventRegistrationToken eventCookie) { return m_events.Remove(eventCookie); }
引发事件,当一个质数计算
将 IsPrime 方法添加到Calculator类的 private 节中。
// Determines whether the input value is prime. bool IsPrime(int n) { if (n < 2) { return false; } for (int i = 2; i < n; ++i) { if ((n % i) == 0) { return false; } } return true; }
当一个质数计算时,请修改 Calculator 的 Add 方法以调用 Microsoft::WRL::EventSource::InvokeAll 方法。
HRESULT __stdcall Add(_In_ int a, _In_ int b, _Out_ int* value) { if (value == nullptr) { return E_POINTER; } int c = a + b; if (IsPrime(c)) { m_events.InvokeAll(c); } *value = c; return S_OK; }
处理从 JavaScript 的事件
在 default.html,请修改 body 节以包含质数的主体。
<div> <input id="a" /> <input id="b" /> <p id="result">Result:</p> <p id="primes" style="color:#808080">Primes found:</p> <button onclick="Add()">Add</button> </div>
在 default.js,请修改 Add 函数处理 PrimeNumberFound 事件。 事件处理程序附加质数为由前面步骤定义的主体。
function Add() { "use strict"; var calculator = new Contoso.Calculator(); calculator.onprimenumberfound = function (ev) { document.getElementById("primes").innerHTML += " " + ev.target; }; var a = document.getElementById("a"); var b = document.getElementById("b"); document.getElementById("result").innerHTML = "Result: " + calculator.add(a.value, b.value); }
备注
在 JavaScript 事件名称更改为小写和前预置" on "与标准命名约定。
下面的插图演示基本的计算器应用。