Coder Social home page Coder Social logo

cppwinrt's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cppwinrt's Issues

Intellisense not working

I just downloaded the latest XDK and tried the included headers in VS2015 Update 3 but Intellisense just doesn't work. Is this how it is supposed to be?
I haven't tried with UWP as we are not at that stage yet.

Are ppl tasks still suppose to work in code based on cppwinrt?

Simply including "winrt/ppl.h" in code causes compile errors. The errors come from its including in its header. In fact, simply including alone causes the same compile errors. doesn't fail in non-winrt/xxx projects.

While I notice that none of this site's samples use ppl, the doc implies that ppl tasks are supported with certain caveats. I am happy to keep experimenting with coroutines, so this isn't stopping me on anything. Still, I am wondering whether the doc is stale or there is a conflict in current cppwinrt and ppl that prevents compiling.

Could we have a little more doc on things like fire_and_forget and adapter? Though I've mimicked the samples and stuff works, I'd rather not have to unravel the templates to infer proper usage.

Intellisense broken?

I'm trying to use this on a DirectX XAML UWP project. If you create one of these projects from the VS template, as soon as you #include a header from the cppwinrt project, intellisense stops working.

I'm simply adding

#include "winrt\base.h"
to the pch.h file and suddenly no intellisense. I'm somewhat of a C++ novice so I can't really figure out what's wrong.

(FYI, I wanted to simply try and rewrite the static methods in DirectXHelper.h to use WinRT/C++. I haven't figured out if this library would be good for anything else at the moment.)

Compile error

When I try to build UWP Project (with compile option /await /std:c++latest, and min. version '10.0.14393.0') to use cppwinrt library,
there's compile error like this

1>  pch.cpp
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\collection.h(2174): error C2039: 'unary_function': is not a member of 'std'
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\unordered_map(14): note: see declaration of 'std'
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\collection.h(2174): error C2504: 'unary_function': base class undefined
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\collection.h(2174): error C2143: syntax error: missing ',' before '<'

about IUnknown

Hi kenny,
first , thanks for this great tool . I'm learning this tool these days and got a confusion :
Is IUnknow belongs to Windows namespace ? if so , how does following line(from base.h/2293) work ?
...
namespace ABI::Windows {

struct __declspec(uuid("af86e2e0-b12d-4c6a-9c5a-d7aa65101e90")) __declspec(novtable) IInspectable : IUnknown
...

many thanks!!!

ListView Control

I tried using ListView Control. But there's a runtime error. Did I something wrong?

this is what I did in C++/CX. and this works.

Platform::Collections::Vector<Platform::String^>^ source
     = ref new Platform::Collections::Vector<Platform::String^>();
source->Append(L"Testing");

ListView^ view = ref new ListView();
view->ItemsSource = source;

this->Content = view;

but this code doesn't work.

ListView listview;
Collections::IVector<hstring> source({ L"Testing" });
listview.ItemsSource(source);

...

window.Content(listview);

Question about Application::Start

Hello, this is not an issue, just a question. I've just started to playing around with cppwinrt and I started with the sample project "XamlCode".

I'm a little bit confused about the following code found in wWinMain:

Application::Start(
[](auto &&) 
{
make<App>();
});

This lambda seems to create an instance of App but it is not returning it to the caller.

My Question: How is the function OnLaunched and other functions like OnWindowsCreated and OnActivated getting called?

I'm just curious.

Thanks for the cppwinrt initiative, it is really needed in my opinion.

SDK Version Directory in Repo

Just a question about the repo structure. Is the intention to have multiple SDK versions supported in the single repo, sitting parallel to the 10.0.14393.0 dir? If not, wouldn't a tagged release be a more traditional approach?

Some place the co_await does not return.

I want to list all the ports connected to my device:
If I use this way, it works,

        ui->listWidget->clear();
    ui->listWidget->addItem("Begin list.....");
    hstring selector = SerialDevice::GetDeviceSelector();
    IAsyncOperation<DeviceInformationCollection> operation =  DeviceInformation::FindAllAsync(selector);
    operation.Completed([&](const auto & sender, AsyncStatus) {
        DeviceInformationCollection devices = sender.GetResults();
        for (DeviceInformation dev : devices)
        {
            QString SN = QString::fromWCharArray(dev.Id().c_str());
            ui->listWidget->addItem(SN);
        }
        ui->listWidget->addItem("End list....");
    });

I will get the info in

operation.Completed( [ & ] ( const auto & sender, AsyncStatus) {

}

but if I use it in this way, it will never return the device info:

    DeviceInformationCollection devices = co_await DeviceInformation::FindAllAsync(selector);
    for (DeviceInformation dev : devices)
    {
        QString SN = QString::fromWCharArray(dev.Id().c_str());
        ui->listWidget->addItem(SN);
    }
    ui->listWidget->addItem("End list....");

the print info "End list" never printed.

Question: get_activation_factory() and caching of non-agile factories

Hello,

Is it by design that for agile objects the activation factory is cached into static variable

    static Interface factory = impl::get_agile_activation_factory<Class, Interface>();

but for non-agile objects get_activation_factory() always calls RoGetActivationFactory()?

    if (!factory)
    {
        return impl::get_activation_factory<Class, Interface>();
    }

I've made small test program that calls get_activation_factory() from main thread and from worker thread. I get the same values.

#include "stdafx.h"

using namespace winrt;
using namespace Windows::Networking;
using namespace Windows::Networking::Connectivity;

using namespace Windows::Security;
using namespace Windows::Security::Credentials;
using namespace Windows::Security::Credentials::UI;

void OtherThread()
{
	initialize();

	const auto& ni1 = get_activation_factory<NetworkInformation, INetworkInformationStatics>();
	printf("WT: ni1 = %p\n", get(ni1));

	const auto& ni2 = get_activation_factory<NetworkInformation, INetworkInformationStatics>();
	printf("WT: ni2 = %p\n", get(ni2));

	const auto& cpo1 = get_activation_factory<CredentialPickerOptions>();
	printf("WT: cpo1 = %p\n", get(cpo1));

	const auto& cpo2 = get_activation_factory<CredentialPickerOptions>();
	printf("WT: cpo2 = %p\n", get(cpo2));

	uninitialize();
}

int main()
{
	initialize();

	std::thread t1(OtherThread);

	t1.join();

	const auto& ni1 = get_activation_factory<NetworkInformation, INetworkInformationStatics>();
	printf("MT: ni1 = %p\n", get(ni1));

	const auto& ni2 = get_activation_factory<NetworkInformation, INetworkInformationStatics>();
	printf("MT: ni2 = %p\n", get(ni2));

	const auto& cpo1 = get_activation_factory<CredentialPickerOptions>();
	printf("MT: cpo1 = %p\n", get(cpo1));

	const auto& cpo2 = get_activation_factory<CredentialPickerOptions>();
	printf("MT: cpo2 = %p\n", get(cpo2));

	uninitialize();

	return 0;
}

Output:

WT: ni1 = 000002036D511850
WT: ni2 = 000002036D511850
WT: cpo1 = 000002036D511BC0
WT: cpo2 = 000002036D511BC0
MT: ni1 = 000002036D511850
MT: ni2 = 000002036D511850
MT: cpo1 = 000002036D511BC0
MT: cpo2 = 000002036D511BC0

Can't you also cache the activation factory for non-agile objects? Something like this:

    if (!factory)
    {
        factory = impl::get_activation_factory<Class, Interface>();  // do not return value, but assign to cache
    }

    return factory;

Or I've picked bad sample classes and getting same factory instances from different threads does not prove anything?

Thanks in advance!

Improve cancellation support

I think that improved cancellation support is needed for the async/await compatible classes this library provides (like IAsyncAction and others, or resumable_io and others.)

Right now, we may have the following "task":

class Some
{
  IAsyncAction keep_alive_task;

  IAsyncAction keep_alive()
  {
    auto cancelled = co_await get_cancellation_token;
    while (!cancelled())
    {
      co_await 10min;
      // do some work
    }
  }
public:
  Some()
  {
    keep_alive_task = keep_alive();
  }

  ~Some()
  {
    keep_alive_task.Cancel();
    try {
      keep_alive_task.get();  // will block for as much as 10 minutes
    } catch(...) {}
  }
};

Currently, we have no way of cancelling that pending timer and will have to wait in Some::~Some until it fires.

While it is possible to create a version of cancellable timer (which I successfully did in my project), this all does not compose well. That is, there is no "connection" between outer cancellation and inner cancellation.

It would be nice to incorporate some solid cancellation support, for example, like in Concurrency Runtime with its cancellation sources, its tokens and subscriptions.

Are there any thoughts or future plans on improving cancellation support?

winrt::attach to C++/CX ref class

The documentation Interoperability Helper Functions talks about using winrt::attach to take ownership of an ABI value to give ownership to a C++/WinRt type. I'd like to use it to get ownership from a C++/CX type, which is stated in the file ~line 83, however, I can't figure out what I need to cast the C++/CX type to in order to use it. I'd love to see an example of this. The code I'm working with is something like this:

RefClass::RefClass(SwapChainPanel^ swapChainPanel)
{
    winrt::Windows::UI::Xaml::Controls::SwapChainPanel panel(nullptr);
    winrt::attach(panel, swapChainPanel);
}

This doesn't compile because it can't convert swapChainPanel into something usable for panel. I'm thinking I need to reinterpret_cast swapChainPanel to an IUnknown and then get the address of the com object, or something of that nature.
Thanks for any suggestions. I really love this library btw.

Question: is there a canonical way to polymorphically cast in/out of IInspectable

Using a platform object like IPropertySet (eg project settings) which polymorphically stores/gets Platform::Objects (now IInspectable), what is the recommended way to store and retrieve its values using cppwinrt?

Reading docs and examples I managed "settings.Lookup(L"CurrentProjectUri").as().ToString()" for retrieval, but storing a string or hstring via settings.Insert is not working: I can't figure out a reasonable dynamic_cast and as/try_as is not found on hstring. What syntax do you recommend?

More details on "specializing" IAsyncOperation<*> and friends

As we can see in the JustCouroutines sample, one has to specialize winrt::ABI::Windows::Foundation::IAsyncOperation and a number of other interfaces in order to use them in the code.

Could someone provide more details on this and the design rationale?

Evidently, as number of "asynchronous" return types grow, we might find ourselves writing more and more of this "boilerplate" code.

Is there a way to simplify this? Or at least provide a macro?

Windows.Devices.Radios may be not work correctly in x86

My OS is win10 64 bit and the OS version is 14393.0. When I build the code in x64, the program works well. However, when in x86, nothing can be gotten from Windows.Devices.Radios. The code is blow.

#pragma comment(lib,"windowsapp")
#include "winrt/Windows.Devices.Radios.h"
using namespace winrt;
using namespace  Windows;
using namespace Windows::Devices::Radios;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;

void test()
{
	auto list = Radio::GetRadiosAsync();
	while (list.Status() != AsyncStatus::Completed)
	{
		Sleep(100);
	}
	IVectorView<Radio> radios = list.GetResults();
	int n = radios.Size();
	auto radioItem = radios.First();

	for (int i = 0; i < radios.Size(); i++)
	{
		Radio r = radioItem.Current();
		radioItem.MoveNext();
	}
	return;
}
int main()
{
	initialize();
	test();
	return 0;
}

Suggestion for interoperating with CX

In order to interoperate with C++/CX, I wrote these two simple converters:

template <typename Trtabi, typename Trt, typename CX>
Trt copyRT(CX cx)
{
    auto abi = reinterpret_cast<Trtabi>(cx);
    Trt res(nullptr);
    winrt::copy_from(res, abi);
    return res;
}

Usage:

auto cxclient = ref new Windows::Web::Syndication::SyndicationClient();

auto rtclient = copyRT<
    winrt::ABI::Windows::Web::Syndication::ISyndicationClient *,
    winrt::Windows::Web::Syndication::SyndicationClient>(cxclient);

and also the opposite:

template <typename CX, typename Trt>
CX copyCX(const Trt& rt)
{
    auto abi = winrt::get(rt);
    auto cx = reinterpret_cast<CX>(abi);
    return cx;
}

Usage:

winrt::Windows::Web::Syndication::SyndicationClient rtclient;

auto cxclient = copyCX<Windows::Web::Syndication::SyndicationClient^>(rtclient);

I would like to see similar converters to be part of the sdk to ease the conversions.
This is of course limited to ref types. I currently just copy the members of the CX value types manually and have no idea on how to make the copy process generic.

Any suggestion to make this stuff 'smarter' is welcome.

AppServiceConnection.OpenAsync() does not return .

Below is my code:

IAsyncAction MainWindow::ConnectToServer()
{
	ui->listWidget->addItem("begin connect111");
	AppServiceConnectionStatus status = co_await m_Connection.OpenAsync();
	if (status == AppServiceConnectionStatus::Success)
	{
		ui->listWidget->addItem("connect success!");
	}
	else
	{
		ui->listWidget->addItem("connect failed!");
	}
}

the "connect success" or "connect failed" message never printed.
but the connection have been built already , I can send message to the server successfully and set the GPIO to make LED light On or OFF.
And when I call AppServiceConnection.Close(), then it print the "connect success" ,seems that the connect function does not return until now.
below is my close function:

void MainWindow::on_CloseBtn_clicked()
{
	m_Connection.Close();
}

I create the AppServiceConnection class as a class member:

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
	IAsyncAction ConnectToServer();
private slots:


IAsyncAction on_LEDOnBtn_clicked();

IAsyncAction on_LEDOffBtn_clicked();

void on_ConnectBtn_clicked();

IAsyncAction on_InitBtn_clicked();

void on_CloseBtn_clicked();

private:
    Ui::MainWindow *ui;
	//TServiceClient m_Client;
	AppServiceConnection m_Connection;
};

and set the service name at construct function:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
	m_Connection.AppServiceName(L"App2AppComService");
	m_Connection.PackageFamilyName(L"TestService_nsmz8dbv8bkn8");
}

Question: c++ constness of value types

From provided samples it seems that you always prefer plain types without const modifier. By old habit I assigned the return value to const references and was confused that for const object I can still call property setters and modify delegates, since all these methods have const modifier, although they clearly modify the object. Would it have any benefits to remove the const modifier from property setters and delegate registration code? I understand that all code is auto-generated from metadata and CLI spec has read/write attributes only for properties. Modern compiler would not be able to know whether arbitrary function modifies the object or not. But at least for properties we can protect against modifying an object. It may give some sense of safety when passing const reference to a class instance as a function argument. Or we just have to forget about c++ constness because WinRT (like .NET) does not support it, because of support for other languages? What would be the best practice regarding const?

Other slightly related question is how to assign result that is returned by winrt function. Whether to assign it to variable of value type X or reference to X?

auto devices = co_await DeviceInformation::FindAllAsync(allReadersSelector);
vs.
auto& devices = co_await DeviceInformation::FindAllAsync(allReadersSelector);

Does both variants have same number of AddRef() calls and there is no real benefit in using reference to value type (which itself is just a wrapped interface pointer)?

Thanks in advance!

Crash after send message to Server in ServiceConnection project

I used these code to connect with the server which is an sample project named "BlinkyService", And I establish an client project, to talk with it via winrtcpp.
this is my code:

void MainWindow::on_WriteBtn_clicked()
{
hstring  requestedPinValue;
    AppServiceConnection connection;
    connection.AppServiceName(L"BlinkyService");
    connection.PackageFamilyName(L"BlinkyService-uwp_gpek5j0d8wyr0");
    IAsyncOperation<AppServiceConnectionStatus> operation =  connection.OpenAsync();
    operation.Completed([&](auto const & sender, AsyncStatus) {
        ui->listWidget->addItem("service connected!");
        AppServiceConnectionStatus status = sender.GetResults();
        if (status != AppServiceConnectionStatus::Success)
        {
            ui->listWidget->addItem("connect failed!");
            return;
        }
        ui->listWidget->addItem("connect success!");
        /*Send a message with the name "requestedPinValue" and the value "High"
        These work like loosely typed input parameters to a method*/
        ValueSet message;
        hstring key = L"requestedPinValue";
        Windows::IInspectable value = PropertyValue::CreateString(L"High");
        message.Insert(key, value);

        IAsyncOperation<AppServiceResponse> resOperation = connection.SendMessageAsync(message);
        //resOperation.Completed([&](const auto & sender2, AsyncStatus) {
        //  AppServiceResponse response = sender2.GetResults();
        //  if (response.Status() == AppServiceResponseStatus::Success)
        //  {
        //      ui->listWidget->addItem("Send message Success!");
        //      //timer = ThreadPoolTimer.CreatePeriodicTimer(this.Tick, TimeSpan.FromMilliseconds(500));
        //  }
        //  else
        //  {
        //      ui->listWidget->addItem("Send message failed!");
        //  }
        //  
        //});


        //If the message was successful, start a timer to send alternating requestedPinValues to blink the LED

    });
}

if I delete the sendMessage code, it will print "connect success!", which means it has been connected to the server... but when I add the sendMessage code, it will crash . Do you know why ?Thank you!

Using Xaml containers

I understand that using XAML markup is not supported in this release. However is it possible to use XAML containers in code. I tried using the Grid and StackPanel classes. I can create objects of those classes but it doesn't look like there is a way to add child controls to them. Is this an issue with the preview or am I doing something wrong?

Porting routine with task.then

I'm having trouble porting a routine that has deals with delayed returns. This is the routine working in cpp/cx.

void MainPage::applyToCard(ConnectFunc connectFunc)
{
	using namespace concurrency;						// For create_task
	using namespace Windows::Devices::SmartCards;		// For SmartCardReader and SmartCard
	using namespace Windows::Devices::Enumeration;
	using namespace Windows::Storage::Streams;			// For IBuffer
	using namespace Windows::Foundation::Collections;	// For IVectorView
	using namespace Windows::Security::Cryptography;		// For CryptographicBuffer

	SmartCardReaderKind readerKind = SmartCardReaderKind::Any;

	if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.Devices.SmartCards.SmartCardConnection")) {
		// SKU supports smart cards 
		Platform::String ^ query = "System.Devices.InterfaceClassGuid:=\"{DEEBE6AD-9E01-47E2-A3B2-A66AA2C036C9}\"";
		if (readerKind != SmartCardReaderKind::Any)
		{
			//	query += " AND System.Devices.SmartCards.ReaderKind:=" + (int)readerKind;
		}


		// See   https://msdn.microsoft.com/windows/uwp/threading-async/asynchronous-programming-in-cpp-universal-windows-platform-apps

		// Added /await to properties | c++ | command line    __resumable ?
		// Windows::Devices::Enumeration::DeviceInformationCollection ^        Windows::Foundation::IAsyncOperation			await
		auto devicesTask = create_task(DeviceInformation::FindAllAsync(query));
		devicesTask.then(
			[this, connectFunc](DeviceInformationCollection^ devices)
		{
			if (0 == devices->Size) {
				TextBlockReaders->Text = "No device for SmartCardConnection";	return;
			}

			for (auto d : devices) {
				if (d->IsEnabled) {
					auto readerName = d->Id;
					auto getTask = create_task(SmartCardReader::FromIdAsync(readerName));
					getTask.then(
						[this, connectFunc](SmartCardReader^ reader)
					{
						TextBlockReaders->Text = reader->Name;
						auto cardsTask = create_task(reader->FindAllCardsAsync());
						cardsTask.then(
							[this, connectFunc](IVectorView<SmartCard^ > ^ cards)
						{
							if (cards->Size > 0) {
								
								SmartCard ^ sc = cards->GetAt(0);
								auto statusTask = create_task(sc->GetStatusAsync());
								statusTask.then(
									[this, sc, connectFunc] ( SmartCardStatus status )
								{
									bool keepGoing= false;
									TextBlockReaders->Text += showStatus(status, keepGoing);
									if (!keepGoing) return;

									// Get the Answer to Reset
									auto atrTask = create_task(sc->GetAnswerToResetAsync());
									atrTask.then(
										[this, sc, connectFunc](IBuffer ^ atr)
									{
										TextBlockAtr->Text = CryptographicBuffer::EncodeToHexString(atr);

										auto connectTask = create_task(sc->ConnectAsync());
										connectTask.then(
											[this, connectFunc](SmartCardConnection ^ conn)
										{
											connectFunc(conn);
										});

									});									
								});
							}
						});
					}); // end lambda
				}
			}
		}
		); // end lambda

	}
}

And my first attempt in cpp/winrt was:

IAsyncOperation<hstring> probeSmartcardAsyn()
	{
		co_await resume_background();

		SmartCardReaderKind readerKind = SmartCardReaderKind::Any;

		if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent(L"Windows.Devices.SmartCards.SmartCardConnection")) {
			// SKU supports smart cards 
			hstring query = L"System.Devices.InterfaceClassGuid:=\"{DEEBE6AD-9E01-47E2-A3B2-A66AA2C036C9}\"";

			auto devices =  co_await DeviceInformation::FindAllAsync(query);
			// auto devicesAsyn = DeviceInformation::FindAllAsync(query);  // no get this time
			if (readerKind != SmartCardReaderKind::Any)
			{
				//	query += " AND System.Devices.SmartCards.ReaderKind:=" + (int)readerKind;
			}

			for (uint32_t dex = 0; dex < devices.Size(); dex++) {
				auto dev = devices.GetAt(dex);
				if (dev.IsEnabled()) {
					return dev.Id();
				}
			
			}

		}
		hstring retval = L"bye";
		return retval;
	}

};

But I had this compiler error on the invocation line 143:

auto retv= co_await probeSmartcardDevsAsyn();

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\experimental/
resumable(44): error C2825: '_Ret': must be a class or namespace when followed by '::'

1>  AndrewApp.cpp(143): note: see reference to class template instantiation
 'std::experimental::coroutine_traits<
	void,
	HelloGui *,
	const winrt::Windows::ApplicationModel::Activation::LaunchActivatedEventArgs &
  >' being compiled

resumable(44): 
	error C2510: '_Ret': left of '::' must be a class/struct/union
	error C2061: syntax error: identifier 'promise_type'
	error C2238: unexpected token(s) preceding ';'

The reference to line 44 is below:

namespace experimental {

	// TEMPLATE CLASS coroutine_traits
	template <typename _Ret, typename... _Ts>
	struct coroutine_traits
	{
Line 44: 	using promise_type = typename _Ret::promise_type;
	};

I can't say I really understand what I'm supposed to do in this area. I suggest examples in this area for the next release, and a list of the crucial building blocks, and what they precisely do.

Why I can not use the winrtcpp in a library project

I created a library project via UWP/virtual c++, it looks like this:
image

and I create a class to list devices:(TServiceClient.cpp)

#include"pch.h"
#include"TServiceClient.h"
IAsyncOperation<int> TServiceClient::ListDevices(char16_t* devinfo)
{
    hstring selector = SerialDevice::GetDeviceSelector();
    DeviceInformationCollection deviceList = co_await DeviceInformation::FindAllAsync(selector);
    for (int i = 0; i < deviceList.Size(); i++)
    {
        int size = sizeof(deviceList.GetAt(i).Id().c_str());
        memcpy(devinfo, deviceList.GetAt(i).Id().c_str(), size);
        devinfo += size;
    }
    return deviceList.Size();
}

(TServiceClient.h)

#pragma once
#include"UWP_Lib.h"
class TServiceClient
{
public:
    IAsyncOperation<int> ListDevices(char16_t* devInfo);
};

Then build it, I get a error :
image

Why does it happens? Thank you!

Provide Headers for Win2D

I realise that the metadata compiler will eventually be released but in the meantime could we have support for Win2D as this would be quite useful.

Where is CoInitializeEx called?

Probably not really related to this Project, but I copied app.cpp, pch.cpp and pch.h to my UWP Project (created with Blank template and deleted App.xaml.* and MainPage.xaml.*).
I get an exception with HRESULT 0x800401f0 (CoInitialize was not called) in wWinMain (Application::Start... line).
Am I missing a project or manifest Setting?

Progress and sticking points with using simple controls

I experimented a bit with some simple controls, and had a bit of success, but was not able to get all the approaches working mentioned in the announcement comments. See the "Won't"s. I just changed the App.cpp in the XamlCode project as follows.

struct App : ApplicationT<App>
{

    void myStyle( TextBlock & block )
    {
        block.FontFamily(FontFamily(L"Segoe UI Semibold"));
        block.FontSize(72.0);
        block.Foreground(SolidColorBrush(Colors::Orange()));
        block.VerticalAlignment(VerticalAlignment::Center);
        block.TextAlignment(TextAlignment::Center);
        block.TextWrapping(TextWrapping::Wrap);
    }

    void myMethod( winrt::Windows::IInspectable const & sender, const Windows::UI::Xaml::RoutedEventArgs & e)
    {
        int w = 3;
    }

    void OnLaunched(LaunchActivatedEventArgs const &)
    {
        Button    button;

        // button.Content( L"Button" ); // Won't work because
                // "cannot convert from 'const wchar_t [7]' to 'const winrt::Windows::IInspectable"

        Windows::IInspectable value = PropertyValue::CreateString(L"Click the button"); // Works 
        button.Content(value);

        // button.Click([=](auto const &&, auto const &&)   {  int w = 5;   });  // Won't compile
        button.Click({ this, &App::myMethod });     // Works.

        Grid grid;

        TextBlock block;
        myStyle(block);

        block.Text( L"hello world" );       

        StackPanel stackPanel;
        stackPanel.HorizontalAlignment( Windows::UI::Xaml::HorizontalAlignment::Center );
        stackPanel.Orientation(winrt::Windows::UI::Xaml::Controls::Orientation::Horizontal );
        stackPanel.Children().Append(block);
        stackPanel.Children().Append(button);


        Window window = Window::Current();
        window.Content(stackPanel);
        window.Activate();
    }
};
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
    Application::Start([](auto &&) { make<App>(); });
}

I believe the button.Click was button::Click in the comments, but no luck with assigning a lambda that way either.
I assume there are a number of ways to create an IInspectable but I'm not too familiar with these classes.

An example that shows how a basic application could be created with C++/WinRT would help people understand what is possible quicker. Also, Intellisense works well and shows the types of the parameters needed if the right parameter type is already present. If you have it wrong, like button.Content( L"Button" ); , then I see nothing helpful.

I'm encouraged by your progress, and I think the goal is good. I hope more documentation and sample generating resources get assigned to the project.

Crash when parse the value set

Below is my code:

void func(){

ValueSet message;
	hstring key = L"Command";
	IInspectable value = PropertyValue::CreateString(L"List");
	message.Insert(key, value);
	
	hstring strrr = message.Lookup(L"Command").as<IPropertyValue>().GetString();

	AppServiceResponse res = m_Client.WriteData(message);
	if (res.Status() == AppServiceResponseStatus::Success)
	{
		ui->ReadList->addItem("list success!");
		ValueSet resMsg =  res.Message();
		auto iter= resMsg.First();;
		do
		{
			auto _ResKey = iter.Current().Key();
			hstring _value =iter.Current().Value().as<IStringable>().ToString();
			ui->ReadList->addItem(QString::fromWCharArray(_ResKey.c_str()));
			ui->ReadList->addItem(QString::fromWCharArray(_value.c_str()));
		} while (iter.MoveNext());
}

First I create a ValueSet and parse it , and I get the value string, is "List", no problem.

ValueSet message;
	hstring key = L"Command";
	IInspectable value = PropertyValue::CreateString(L"List");
	message.Insert(key, value);
	
	hstring strrr = message.Lookup(L"Command").as<IPropertyValue>().GetString();

And then I send it to the server, and get a response, I get the message of the response, and parse it,

ValueSet resMsg =  res.Message();
		auto iter= resMsg.First();;
		do
		{
			auto _ResKey = iter.Current().Key();
			hstring _value =iter.Current().Value().as<IStringable>().ToString();
			ui->ReadList->addItem(QString::fromWCharArray(_ResKey.c_str()));
			ui->ReadList->addItem(QString::fromWCharArray(_value.c_str()));
		} while (iter.MoveNext());

I can get the key of every iter of the response message successfully, no crash, they are sent by the server , and when I parse the value, then the program crashed.
I tried to use the IPropertyValue to convert the IInspectable, but also crash.

Manipulation events give linker errors

If you try to create a lambda from a manipulation event (like ManipulationStarted), it throws a linker error. I am including both the winrt/Windows.UI.Input.h and winrt/Windows.UI.Xaml.h headers.

I am still trying to sort out what is wrong here...

wintrt::initialize throws when already initialized

In base.h:

inline void initialize(const initialize_type type = initialize_type::multi_threaded)
{
    check_hresult(WINRT_RoInitialize(static_cast<uint32_t>(type)));
}

You are allowed to call RoInitialize more than once but it returns S_FALSE if it's already initialized. The problem is that check_hresult only accepts S_OK and throws on S_FALSE.

Either check_hresult should use FAILED(result) instead of result != S_OK or initialize should be implemented as follows to avoid using check_hresult:

inline void initialize(const initialize_type type = initialize_type::multi_threaded)
{
    HRESULT result = WINRT_RoInitialize(static_cast<uint32_t>(type)));
    if (FAILED(result))
    {
        impl::throw_hresult(result);
    }
}

What project template is used to kick start cppwinrt?

What project template if any do you use to kick start a C++ UWP solution using cppwinrt (Blank C++ UWP APP)? It would also be helpful to show real XAML integration. A simple multi-page XAML app would be a good start. A redo of the RSS reader sample would certainly cover a lot of ground.

Lastly, showing a sample that integrates cppwinrt with C#/XAML solution would be most welcome; two variants, C# as the GUI and cppwinrt providing a component service, and cppwinrt as the GUI and C# providing the component service.

xaml file

In this release, how can load and initialize a xaml file?

How to write a ServiceConnection program?

I am doing it with winrtcpp like this in my qt program :
`AppServiceConnection appServiceConnection;

ValueSet message;
hstring key = L"Command";
Windows::Foundation::IPropertyValue value ;
value = "aaa";
message.Insert(key, value);
IAsyncOperation<AppServiceResponse> response =  appServiceConnection.SendMessageAsync(message);
response.Completed([&](const auto & sender, AsyncStatus) {
    AppServiceResponse res = sender.GetResults();
    ui->listWidget->addItem("send message success!");
});`

But I received a compile error, that "aaa"can not be converted to a IPropertyValue type value. So which type can I use in this place?

Compile errors when including Windows.UI.Xaml.Media.h

I could reproduce the problem by starting from the Blocks sample.
Just add the pch.h file and add the following include:

include "winrt\Windows.UI.Xaml.Media.h"

Recompiling the sample, now I get these errors:

1>------ Build started: Project: Blocks, Configuration: Debug x64 ------
1>          1 file(s) copied.
1>  pch.cpp
1>h:\samples\cppwinrt\10.0.14393.0\winrt\base.h(433): error C2504: 'winrt::Windows::Media::Playback::impl_IMediaPlaybackSource<D>': base class undefined
1>          with
1>          [
1>              D=winrt::Windows::Media::Core::IMediaSource2
1>          ]
1>  h:\samples\cppwinrt\10.0.14393.0\winrt\base.h(441): note: see reference to class template instantiation 'winrt::impl::require_one<D,winrt::Windows::Media::Playback::IMediaPlaybackSource>' being compiled
1>          with
1>          [
1>              D=winrt::Windows::Media::Core::IMediaSource2
1>          ]
1>  h:\samples\cppwinrt\10.0.14393.0\winrt\internal\windows.media.core.2.h(1345): note: see reference to class template instantiation 'winrt::impl::require<winrt::Windows::Media::Core::IMediaSource2,winrt::Windows::Foundation::IClosable,winrt::Windows::Media::Playback::IMediaPlaybackSource>' being compiled
1>  h:\samples\cppwinrt\10.0.14393.0\winrt\base.h(7259): note: see reference to class template instantiation 'winrt::com_ptr<IContextCallback>' being compiled
1>  h:\samples\cppwinrt\10.0.14393.0\winrt\base.h(1483): note: see reference to class template instantiation 'winrt::com_ptr<IRestrictedErrorInfo>' being compiled
1>h:\samples\cppwinrt\10.0.14393.0\winrt\base.h(433): error C2504: 'winrt::Windows::Media::Playback::impl_IMediaPlaybackSource<D>': base class undefined
1>          with
1>          [
1>              D=winrt::Windows::Media::Core::IMediaSource3
1>          ]
1>  h:\samples\cppwinrt\10.0.14393.0\winrt\base.h(441): note: see reference to class template instantiation 'winrt::impl::require_one<D,winrt::Windows::Media::Playback::IMediaPlaybackSource>' being compiled
1>          with
1>          [
1>              D=winrt::Windows::Media::Core::IMediaSource3
1>          ]
1>  h:\samples\cppwinrt\10.0.14393.0\winrt\internal\windows.media.core.2.h(1354): note: see reference to class template instantiation 'winrt::impl::require<winrt::Windows::Media::Core::IMediaSource3,winrt::Windows::Foundation::IClosable,winrt::Windows::Media::Core::IMediaSource2,winrt::Windows::Media::Playback::IMediaPlaybackSource>' being compiled
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Provide a conversion from winrt::ABI::<type>* to ::ABI::<type>*

By declaring your own ABI types you lead to frustrating errors like this one:

rror C2664: 'HRESULT ABI::Microsoft::Graphics::Canvas::ICanvasDeviceStatics::CreateFromDirect3D11Device(ABI::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice *,ABI::Microsoft::Graphics::Canvas::ICanvasDevice **)': cannot convert argument 1 from 'winrt::ABI::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice *' to 'ABI::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice *'

I can work around this but it is inconvenient.

It also makes functions like this harder to use:

HRESULT WINAPI CreateDirect3D11DeviceFromDXGIDevice(
In IDXGIDevice *dxgiDevice,
Out IInspectable **graphicsDevice
);

You have to remember to use ::IInspectable instead of IInspectable because in a winrt class that is winrt::IInspectable.

BTW it would be nice if the windows SDK included nice wrappers in C++/winrt for functions like this.

Create declarations for interop interfaces in winrt

At the moment, if you want to use the interop types in e.g. windows.ui.composition.interop.h you have to include the include file from the sdk which declares them in ::ABI and you have to consume them with a winrt::com_ptr. It would be nice to be able to use those directly in winrt or at the least have them in winrt::ABI. Otherwise, using namespace winrt; makes ABI ambiguous meaning you have to say ::ABI or winrt::ABI.

How to: Extract a string from a Button Context

void myButtonClick(winrt::Windows::IInspectable const & sender, const Windows::UI::Xaml::RoutedEventArgs & args )
{
    Button sendButton = sender.as<Button>();
    auto senderContent = sendButton.Content().as< SomeTypeIGuess >(); 
                                 // What type can I use to get the Context from a Button?

    textBlock.Text(L"Method hit");
}

I was wondering how I can use the passed parameters for a button click. I made some progress to get the Button from the sender, but how do I get the Button's Content as a string of some sort?

Reason for "Unresolved symbol winrt::Windows::UI::Xaml::Input::TappedEventHandler" ?

void myButtonTapped(
    winrt::Windows::IInspectable const & sender,
    const Windows::UI::Xaml::RoutedEventArgs & args)
{
    textBlock.Text( L"Tapped" );
}

void OnLaunched(LaunchActivatedEventArgs const &)
{
    buttonM.Tapped({ this, &HelloGui::myButtonTapped });
    // error LNK2019 : unresolved external symbol winrt::Windows::UI::Xaml::Input::TappedEventHandler::TappedEventHandler
    //  <class HelloGui,void (__cdecl HelloGui::*)(struct winrt::Windows::IInspectable const &,struct winrt::Windows::UI::Xaml::RoutedEventArgs const &)>
    // 
    // referenced in function HandleTapped(void)

I thought to try a button Tapped event handler instead of a Click. It compiled, but did not link.

check_hresult throws if HRESULT is S_FALSE.

S_OK and S_FALSE are defined as a success codes, but check_hresult only checks for S_OK.

This is especially annoying when using setters of properties, which return S_FALSE if their value didn't change. Currently one needs to wrap all setters inside a try-catch block or use obj->put_X, ignoring the result.

I suggest changing the implementation from

__forceinline void check_hresult(const HRESULT result)
{
    if (result != S_OK)
    {
        impl::throw_hresult(result);
    }
}

to

__forceinline void check_hresult(const HRESULT result)
{
    if (FAILED(result))
    {
        impl::throw_hresult(result);
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.