Share via


如何:利用 WRL 啟動與使用 Windows 執行階段元件

本檔說明如何使用 Windows 執行階段 C++ 樣板庫 (WRL)來初始化Windows 執行階段,以及如何啟動和使用Windows 執行階段元件。

若要使用元件,您必須取得元件所實作之類型的介面指標。 由於Windows 執行階段的基礎技術是元件物件模型 (COM),因此您必須遵循 COM 規則來維護類型的實例。 例如,您必須維護 參考計數 ,以判斷類型何時從記憶體中刪除。

為了簡化Windows 執行階段的使用,Windows 執行階段 C++ 樣板庫會提供自動執行參考計數的智慧型指標範本 ComPtr < T > 。 當您宣告變數時,請指定 ComPtr< 介面名稱 > 識別碼。 若要存取介面成員,請將箭頭成員存取運算子 ( -> ) 套用至識別碼。

重要

當您呼叫介面函式時,請一律測試 HRESULT 傳回值。

啟用和使用Windows 執行階段元件

下列步驟會使用 Windows::Foundation::IUriRuntimeClass 介面來示範如何建立Windows 執行階段元件的啟用處理站、建立該元件的實例,以及擷取屬性值。 它們也會示範如何初始化Windows 執行階段。 完整的範例如下。

重要

雖然您通常會在 通用 Windows 平臺 (UWP) 應用程式中使用 Windows 執行階段 C++ 樣板程式庫,但此範例會使用主控台應用程式來說明。 這類 wprintf_s 功能無法從 UWP 應用程式取得。 如需您可以在 UWP 應用程式中使用之類型和函式的詳細資訊,請參閱 通用 Windows 平臺 應用程式和適用于 UWP 應用程式的 Win32 和 COM 中不支援 CRT 函式。

若要啟動和使用Windows 執行階段元件

  1. 包含 ( #include ) 任何必要的Windows 執行階段、Windows 執行階段 C++ 樣板庫或 C++ 標準程式庫標頭。

    #include <Windows.Foundation.h>
    #include <wrl\wrappers\corewrappers.h>
    #include <wrl\client.h>
    #include <stdio.h>
    
    using namespace ABI::Windows::Foundation;
    using namespace Microsoft::WRL;
    using namespace Microsoft::WRL::Wrappers;
    

    建議您在 .cpp 檔案中使用 using namespace 指示詞,讓程式碼更容易閱讀。

  2. 初始化應用程式執行所在的執行緒。 每個應用程式都必須初始化其執行緒和執行緒模型。 這個範例會使用 Microsoft::WRL::Wrappers::RoInitializeWrapper 類別來初始化Windows 執行階段,並將RO_INIT_MULTITHREADED 指定 為執行緒模型。 類別 RoInitializeWrapper 會在建構時呼叫 Windows::Foundation::Initialize ,並在 Windows::Foundation::Uninitialize 終結時呼叫。

    // Initialize the Windows Runtime.
    RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
    if (FAILED(initialize))
    {
        return PrintError(__LINE__, initialize);
    }
    

    在第二個語句中 ,RoInitializeWrapper::HRESULT 運算子會從 對 的呼叫 Windows::Foundation::Initialize 傳回 HRESULT

  3. 建立 介面的 ABI::Windows::Foundation::IUriRuntimeClassFactory 啟用處理站

    // Get the activation factory for the IUriRuntimeClass interface.
    ComPtr<IUriRuntimeClassFactory> uriFactory;
    HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(), &uriFactory);
    if (FAILED(hr))
    {
        return PrintError(__LINE__, hr);
    }
    

    Windows 執行階段會使用完整名稱來識別類型。 參數 RuntimeClass_Windows_Foundation_Uri 是Windows 執行階段所提供的字串,並包含必要的執行時間類別名稱。

  4. 初始化代表 URI "https://www.microsoft.com" 的 Microsoft::WRL::Wrappers::HString 變數。

    // Create a string that represents a URI.
    HString uriHString;
    hr = uriHString.Set(L"http://www.microsoft.com");
    if (FAILED(hr))
    {
        return PrintError(__LINE__, hr);
    }
    

    在Windows 執行階段中,您不會為Windows 執行階段將使用的字串配置記憶體。 相反地,Windows 執行階段會在它維護及用於作業的緩衝區中建立字串複本,然後將控制碼傳回它所建立的緩衝區。

  5. IUriRuntimeClassFactory::CreateUri使用 Factory 方法來建立 ABI::Windows::Foundation::IUriRuntimeClass 物件。

    // Create the IUriRuntimeClass object.
    ComPtr<IUriRuntimeClass> uri;
    hr = uriFactory->CreateUri(uriHString.Get(), &uri);
    if (FAILED(hr))
    {
        return PrintError(__LINE__, hr);
    }
    
  6. IUriRuntimeClass::get_Domain呼叫 方法來擷取 屬性的值 Domain

    // Get the domain part of the URI.
    HString domainName;
    hr = uri->get_Domain(domainName.GetAddressOf());
    if (FAILED(hr))
    {
        return PrintError(__LINE__, hr);
    }
    
  7. 將功能變數名稱列印至主控台並傳回。 所有 ComPtr 和 RAII 物件都會離開範圍,並會自動釋放。

    // Print the domain name and return.
    wprintf_s(L"Domain name: %s\n", domainName.GetRawBuffer(nullptr));
    
    // All smart pointers and RAII objects go out of scope here.
    

    WindowsGetStringRawBuffer 函式會擷取 URI 字串的基礎 Unicode 格式。

以下是完整的範例:

// wrl-consume-component.cpp
// compile with: runtimeobject.lib
#include <Windows.Foundation.h>
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
#include <stdio.h>

using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;

// Prints an error string for the provided source code line and HRESULT
// value and returns the HRESULT value as an int.
int PrintError(unsigned int line, HRESULT hr)
{
    wprintf_s(L"ERROR: Line:%d HRESULT: 0x%X\n", line, hr);
    return hr;
}

int wmain()
{
    // Initialize the Windows Runtime.
    RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
    if (FAILED(initialize))
    {
        return PrintError(__LINE__, initialize);
    }

    // Get the activation factory for the IUriRuntimeClass interface.
    ComPtr<IUriRuntimeClassFactory> uriFactory;
    HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(), &uriFactory);
    if (FAILED(hr))
    {
        return PrintError(__LINE__, hr);
    }

    // Create a string that represents a URI.
    HString uriHString;
    hr = uriHString.Set(L"http://www.microsoft.com");
    if (FAILED(hr))
    {
        return PrintError(__LINE__, hr);
    }

    // Create the IUriRuntimeClass object.
    ComPtr<IUriRuntimeClass> uri;
    hr = uriFactory->CreateUri(uriHString.Get(), &uri);
    if (FAILED(hr))
    {
        return PrintError(__LINE__, hr);
    }

    // Get the domain part of the URI.
    HString domainName;
    hr = uri->get_Domain(domainName.GetAddressOf());
    if (FAILED(hr))
    {
        return PrintError(__LINE__, hr);
    }

    // Print the domain name and return.
    wprintf_s(L"Domain name: %s\n", domainName.GetRawBuffer(nullptr));

    // All smart pointers and RAII objects go out of scope here.
}
/*
Output:
Domain name: microsoft.com
*/

編譯程式碼

若要編譯器代碼,請複製程式碼,然後將它貼到 Visual Studio 專案中,或貼到名為 wrl-consume-component.cpp 的檔案中,然後在 Visual Studio 命令提示字元視窗中執行下列命令。

cl.exe wrl-consume-component.cpp runtimeobject.lib

另請參閱

Windows 執行階段 C++ 範本庫 (WRL)