Windows Runtime Cpp Windowsランタイムテンプレートライブラリ

提供:yonewiki
2022年9月26日 (月) 11:49時点におけるYo-net (トーク | 投稿記録)による版 (ページの作成:「Windows Runtime Cppへ戻る == '''概要''' == WindowsRuntimeTemplateLiblaryはWindowsランタイムをより簡単に扱うことを実現するテンプレートです。WRLと略されます。 *wrl/client.h *wrl/wrappers/corewrapers.h の2つのヘッダファイルをインクルードすることで利用できます。 == '''初期化 RoInitializeWrappers obj()''' == テンプレートライブラリを利用する場合はインクルードファイ…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)

Windows Runtime Cppへ戻る


概要

WindowsRuntimeTemplateLiblaryはWindowsランタイムをより簡単に扱うことを実現するテンプレートです。WRLと略されます。

  • wrl/client.h
  • wrl/wrappers/corewrapers.h

の2つのヘッダファイルをインクルードすることで利用できます。

初期化 RoInitializeWrappers obj()

テンプレートライブラリを利用する場合はインクルードファイルの指定に加えて名前空間Microsoft::WRL::Wrappersを頻繁に利用するのでusing namespaceで指定します。そしてRoInitializeの代わりにRoInitializeWrapperオブジェクトの生成によって初期化できます。

  • RoInitializeWrapper initialize(RO_INIT_TYPE::RO_INIT_MULTITHREADED);

通常は上記のようなRoInitializeWrapperオブジェクトの生成処理によって初期化ができます。

#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#include <crtdbg.h>
#include <roapi.h>

#include <wrl/client.h>
#include <wrl/wrappers/corewrappers.h>

using namespace Microsoft::WRL::Wrappers;


int main()
{
	HRESULT HRESULT_Hr;
	setlocale(LC_ALL, "");
	
	RoInitializeWrapper initialize(RO_INIT_TYPE::RO_INIT_MULTITHREADED);
	if (FAILED(initialize)) { wprintf(L"WRLの初期化に失敗しました。\n"); }
	else                    { wprintf(L"WRLの初期化に成功しました。\n"); }



	_wsystem(L"pause");
	return 0;

}

実行結果

WRLの初期化に成功しました。
続行するには何かキーを押してください . . .


文字列 HString

HSTRINGと非常に似ているHString型が利用できます。何が違うかというと、大文字と小文字の差であることとWRL(テンプレートライブラリのオブジェクト)であることとメソッドの名前が少し違うことや引数の取り方が違うことなのかもしれません。まずは基本的なHStringの使い方のサンプルを示します。HStirngオブジェクトのメソッドSetやGetRawBufferについては後述したいと思います。HStringは名前空間Microsoft::WRL::Wrappersに定義されている文字列のためのクラスです。

  • HString obj

通常は上記のようなHStringオブジェクトの生成処理によって初期化ができます。サンプルでは22行目で使われています。

#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#include <crtdbg.h>
#include <roapi.h>

#include <wrl/client.h>
#include <wrl/wrappers/corewrappers.h>

using namespace Microsoft::WRL::Wrappers;


int main()
{
	HRESULT HRESULT_Hr;
	setlocale(LC_ALL, "");
	
	RoInitializeWrapper initialize(RO_INIT_TYPE::RO_INIT_MULTITHREADED);
	if (FAILED(initialize)) { wprintf(L"WRLの初期化に失敗しました。\n"); }
	else                    { wprintf(L"WRLの初期化に成功しました。\n"); }

	HString HString_Str;
	HRESULT_Hr = HString_Str.Set(L"ワイド文字列HStringオブジェクト");
	if (FAILED(HRESULT_Hr)) {
		wprintf_s(L"HStringオブジェクトの設定に失敗しました。\n");
		_CrtDbgBreak();
		return 0;
	}
	else {
		wprintf_s(L"HStringオブジェクトの設定に成功しました。\n");
	}

	wprintf_s(L"HString HString_Str=%s\n",HString_Str.GetRawBuffer(nullptr));

	_wsystem(L"pause");
	return 0;

}

実行結果

WRLの初期化に成功しました。
HStringオブジェクトの設定に成功しました。
HString HString_Str=ワイド文字列HStringオブジェクト
続行するには何かキーを押してください . . .

文字列の設定 HString Obj.Set()

前項のサンプルのとおりの使い方です。

  • (HString型オブジェクト).Set(ワイド文字列リテラルもしくはワイド文字列先頭アドレス);

上記のようにして文字列値をオブジェクトに格納させることができます。

第一引数:設定した文字列を指定します。サンプルでは23行目に使われていて、L"ワイド文字列HStringオブジェクト"のようにワイド文字列リテラルを指定しています。


文字列の設定 HString Obj.GetRawBuffer()

前項のサンプルのとおりの使い方です。

  • (HString型オブジェクト).GetRawBuffer(取得する文字数);

上記のようにして文字列値をオブジェクトに格納させることができます。

第一引数:取得する文字数を指定します。指定しない場合はnullptrなどのヌルポインタを設定します。サンプルでは33行目に使われていて、nullptrとして、文字列の長さ指定をしていません。したがって保持している文字列で\0(ヌル文字)が登場するまでを取得することができます。

ComPtr スマートポインタによる文字列オブジェクト生成

COMでも使われるIUnknownインターフェースをオーバラップ(包み込む)したComPtr型が使われます。ComPtrは名前空間Microsoft::WRLに定義されているテンプレートです。ComPtrクラスに<IApplication>型として利用するようなテンプレートの使い方です。これをCOMの技術が使われたComPtrクラスで扱うことで文字列オブジェクトの操作ができます。具体的には以下のようにしてIApplicationのスマートポインタとしてのComPtrテンプレートを使った変数を生成します。


  • ComPtr <IApplication> Obj


生成されてポインタ変数を使って、Windowsランタイムオブジェクトを生成し、そのオブジェクト名を取得するメソッドを使う文字列操作のサンプルを以下に示します。ComPtrはオブジェクトが消滅するとき(関数を抜けるときやメイン関数が終わるとき)にComPtrを使って生成したものも纏めて消滅(破棄)させるように働くので終了処理部分もすっきりします。


#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#include <crtdbg.h>
#include <roapi.h>

#include <wrl/client.h>
#include <wrl/wrappers/corewrappers.h>
#include <windows.ui.xaml.h>

using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::UI::Xaml;

int main()
{
	HRESULT HRESULT_Hr;
	setlocale(LC_ALL, "");
	
	RoInitializeWrapper initialize(RO_INIT_TYPE::RO_INIT_MULTITHREADED);
	if (FAILED(initialize)) { wprintf(L"WRLの初期化に失敗しました。\n"); }
	else                    { wprintf(L"WRLの初期化に成功しました。\n"); }


	ComPtr <IApplication> CoIApplicationObj;

	HRESULT_Hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Application).Get(),(IInspectable**)CoIApplicationObj.GetAddressOf());
	if (FAILED(HRESULT_Hr)) {
		wprintf_s(L"Runtimeオブジェクトの生成に失敗しました。\n");
		_CrtDbgBreak();
		return 0;
	}
	else {
		wprintf_s(L"Runtimeオブジェクトの生成に成功しました。\n");
	}

	HString HString_StrClassName;
	HRESULT_Hr = CoIApplicationObj.Get()->GetRuntimeClassName(HString_StrClassName.GetAddressOf());
	if (FAILED(HRESULT_Hr)) {
		wprintf_s(L"HString ClassName文字列の生成に失敗しました。\n");
		_CrtDbgBreak();
		return 0;
	}
	else {
		wprintf_s(L"HString ClassName文字列の生成に成功しました。\n");
	}
	wprintf_s(L"\n");
	wprintf_s(L"HString HString_StrClassName=%s\n", HString_StrClassName.GetRawBuffer(nullptr));
	wprintf_s(L"\n");


	HString HString_Str;
	HRESULT_Hr = HString_Str.Set(L"ワイド文字列HStringオブジェクト");
	if (FAILED(HRESULT_Hr)) {
		wprintf_s(L"HStringオブジェクトの設定に失敗しました。\n");
		_CrtDbgBreak();
		return 0;
	}
	else {
		wprintf_s(L"HStringオブジェクトの設定に成功しました。\n");
	}

	wprintf_s(L"\n");
	wprintf_s(L"HString HString_Str=%s\n",HString_Str.GetRawBuffer(nullptr));
	wprintf_s(L"\n");

	HString_Str.Release();
	HString_StrClassName.Release();

	_wsystem(L"pause");
	return 0;

}

実行結果

WRLの初期化に成功しました。
Runtimeオブジェクトの生成に成功しました。
HString ClassName文字列の生成に成功しました。

HString HString_StrClassName=Windows.UI.Xaml.Application

HStringオブジェクトの設定に成功しました。

HString HString_Str=ワイド文字列HStringオブジェクト

続行するには何かキーを押してください . . .


HString::MakeReference(pStr).Get() 静的メンバ関数

前項のサンプルに登場したHStringクラスの静的メンバ関数MakeReferenceを使うと文字列を参照するオブジェクトが生成されます。

  • HString::MakeReference(文字列先頭アドレス変数or L"" 文字列リテラル指定).Get()

上記のようにして、ネイティブなC++文字列変数からHString型の文字列の参照をオブジェクトとして作ることができます。

第一引数:文字列の先頭アドレス変数 L""のようなワイド文字列のリテラルを指定しても同じことです。サンプルでは27行目で使われていて、ヘッダファイルで定義されているRuntimeClass_Windows_UI_Xaml_ApplicationというキーワードでL"RuntimeClass.Windows.UI.Xaml.Application"が指定されているような感じになっています。


ComPtr <IApplication> Obj.GetAddressOf()

前項のサンプルに登場したComPtrの< >テンプレート(例ではIApplicationクラス)によって定義されたオブジェクト(例ではObj)のメソッドGetAddressOf()関数によってObjのアドレスを返却する関数となっています。

  • ComPtr <IApplication> Obj.GetAddressOf()
引数はありません。

RoActivateInstanceなどオブジェクトのアドレスを引数として必要とする関数を使うときに便利なメソッドとなります。


ComPtr <IApplication> Obj.Get()

前項のサンプルに登場したComPtrの< >テンプレート(例ではIApplicationクラス)によって定義されたオブジェクト(例ではObj)のメソッドGet()関数によってObjのオブジェクトを返却する関数となっています。

  • ComPtr <IApplication> Obj.Get()
引数はありません。

サンプルでは38行目に使われています。ObjはIApplicationオブジェクトのアドレスを保持している変数ですので、IApplicationクラスのメンバ関数GetRuntimeClassNameをアロー演算子を使って指定できています。

文字列の設定 HString Obj.GetAddressOf()

前項のサンプルのとおりの使い方です。

  • (HString型オブジェクト).GetAddressOf();

上記のようにして文字列値の先頭アドレスを取得できます。引数としてHString型の先頭アドレスが必要な場合に便利です。

引数はありません。

サンプルでは38行目に使われています。このようにCOMテンプレートで準備されているメソッドと同じ名前で統一されています。すべてのメソッドを少しづつ紹介したいとは思いますが、めちゃくちゃ多いので、全部紹介するまでに他のこともやらんといかんし、たぶん…先に管理人の命が尽きる気がします。


Windows Runtime Cppへ戻る