C ++ / WinRTを使用して、カスタムXAMLコントロールをコードに実装しようとしています。しかし、私の試みた実装はコンパイルに失敗しました。概念実証として、私はこのコードを使用していました。
#pragma once
#include <winrt/Windows.UI.Xaml.Controls.h>
namespace MyApp
{
struct MyControl : winrt::implements<MyControl, winrt::Windows::UI::Xaml::Controls::Control>
{
};
}
これにより、次のコンパイラエラーが発生しました。
1>MyControl.cpp 1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(6416): error C2079: 'winrt::impl::producer<D,winrt::Windows::UI::Xaml::Controls::Control,void>::vtable' uses undefined struct 'winrt::impl::produce<D,I>' 1> with 1> [ 1> D=MyApp::MyControl 1> ] 1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(7163): note: see reference to class template instantiation 'winrt::impl::producer<D,winrt::Windows::UI::Xaml::Controls::Control,void>' being compiled 1> with 1> [ 1> D=MyApp::MyControl 1> ] 1>c:\xxx\mycontrol.h(8): note: see reference to class template instantiation 'winrt::implements<MyApp::MyControl,winrt::Windows::UI::Xaml::Controls::Control>' being compiled
コンパイラエラーを理解できません。どうやら、Windowsランタイムで使用する他のタイプを実装するのと同じ方法でXAMLコントロールを実装することはできません。
XAMLカスタムコントロールをコードに実装するには何が必要ですか?
WinRTの「継承」または「サブクラス化」は、C ++の継承とは微妙に異なります。これらはCOMインターフェイスであるため、WinRTランタイムクラスをサブクラス化する場合、実際に実行しているのはCOM集約であり、基本タイプのオーバーライド可能なインターフェイスの実装と組み合わされています。COM集約の側面により、これは標準のC ++継承よりもかなり面倒であり、すべての委任/非委任、特別な構築などがあります。これはWRLの大きな問題ですが、C ++ / CXは以下のコンパイラマジックを実行しました。これを抽象化するためのフード。幸い、C ++ / WinRTは、目に見えない魔法に頼ることなく、2種類の抽象化を提供するのに役立ちます。
外部から表示する必要のないタイプ(ランタイムコンポーネントではなくアプリなど)を作成している場合、C ++ / WinRTはこれに便利なヘルパーを提供します。
#pragma once
#include <winrt/Windows.UI.Xaml.Controls.h>
namespace MyApp
{
struct MyControl : winrt::Windows::UI::Xaml::Controls::ControlT<MyControl>
{
void OnTapped(winrt::Windows::UI::Xaml::Input::TappedRoutedEventArgs const&);
};
}
この基本型ControlT
は、集約された基本Control
インスタンスを正しく構築し、基本メソッドをそれに委任すると同時に、「オーバーライド可能な」インターフェースを実装します。これらのオーバーライド可能なメソッドにはすべて、デフォルトで基本メソッドを呼び出すプレースホルダー実装が与えられていますが、自分でオーバーライドしてカスタム動作を取得することもできます。
一方、IDLを介して、投影される型を作成する必要がある場合は、次のようにします。
namespace MyApp
{
[default_interface]
runtimeclass MyControl : Windows.UI.Xaml.Controls.Control
{
MyControl();
};
}
これControlT
により、上記の組み込みの場合と同様のスキャフォールディングが生成されますが、タイプも投影されます。実際、このタイプ(この例ではMyControl.gh)について生成されたファイルを調べると、MyControlT
すべてが接続されている場所がわかります。
(注:この[default_interface]
属性は、空の、構築可能な、封印されたランタイムクラスがある場合にのみ必要です。メンバーを追加すると、midlは、他の同軸化なしでデフォルトのインターフェースを合成します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加