演练:使用 WRL 创建基本 Windows 运行时组件

本文档演示如何使用 Windows 运行时 C++ 模板库 (WRL) 创建一个基本的 Windows 运行时 元素。该结果质数时,元素将两个数相加并引发事件。本文档还演示如何使用 JavaScript 从 Windows 应用商店 app 的元素。

系统必备

创建两个数字相加的基本 Windows 运行时 元素

  1. 在 Visual Studio 中,创建一个 Visual C++ WRLClassLibrary 项目。文档 WRL 类库项目模板 描述如何下载该模板。将项目命名为 Contoso。

  2. 在 Contoso.cpp 和 Contoso.idl,请在“计算器”替换“WinRTClass”的所有实例。

  3. 在 Contoso.idl,添加 Add 方法。ICalculator 接口。

    HRESULT Add([in] int a, [in] int b, [out, retval] int* value);
    
  4. 在 Contoso.cpp,添加 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 应用商店 app 的元素

  1. 在 Visual Studio 中,添加一个新的 JavaScript 空白应用程序 项。Contoso 解决方案。将项目命名为 CalculatorJS。

  2. 在 CalculatorJS 项目中,添加对 Contoso 项目。

  3. 在 default.html,请在这些 UI 元素替换 body 部分:

    <div>
        <input id="a" />
        <input id="b" />
        <p id="result">Result:</p>
        <button onclick="Add()">Add</button>
    </div>
    
  4. 在 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,方法名称的首字母大写更改为例与标准命名约定。

添加激发的事件。,在一个质数计算

  1. 在 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;
    
    };
    
  2. ICalculator 接口,定义 PrimeNumberFound 事件。eventaddeventremove 属性指定 ICalculator 接口的使用者可以订阅和从此取消订阅事件。

    [eventadd]
    HRESULT PrimeNumberFound(
        [in] PrimeNumberEvent* eventHandler, 
        [out, retval] EventRegistrationToken* eventCookie);
    [eventremove] 
    HRESULT PrimeNumberFound(
        [in] EventRegistrationToken eventCookie);
    
  3. 在 Contoso.cpp,添加一个 privateMicrosoft::WRL::EventSource 成员变量管理活动用户和调用事件处理程序。

    EventSource<IPrimeNumberEvent> m_events;
    
  4. 在 Contoso.cpp,请执行 add_PrimeNumberFoundremove_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);
    }
    

引发事件,当一个质数计算

  1. 在 Contoso.cpp,添加 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;
    }
    
  2. 在一个质数计算时,请修改 CalculatorAdd 方法调用 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 的事件

  1. 在 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>
    
  2. 在 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 "符合条件的命名约定。

下图显示了基本计算器应用程序。

使用 JavaScript 的基本计算器应用程序

请参见

概念

Windows 运行时 C++ 模板库 (WRL)

WRL 类库项目模板

C/C++ 代码分析工具