microsoft / cppwinrt Goto Github PK
View Code? Open in Web Editor NEWC++/WinRT
License: MIT License
C++/WinRT
License: MIT License
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.
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.
Sorry for a rookie question (possibly not an issue), but how do I get a TypeName instance which I can pass to the Windows::UI::XAML::Controls::Frame::Navigate(...) method?
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.)
winrt::hstring has an operator std::wstring. It would be convenient to have a std::wstring_view now that this has been implemented in VC++.
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 '<'
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!!!
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);
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.
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?
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.
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!
I tried to compile the code in C++/WinRT: Getting Started with /std:c++latest
, but I got tons of compile error.
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?
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.
Are there any plan on supporting MinGW or clang ?
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?
In the video Universal Windows Apps with Standard C++ Kenny Kerr uses modern.exe to generate basic projects, which is great.
Is this modern.exe tool available somewhere ?
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?
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;
}
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.
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");
}
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!
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!
vcpkg install cppwinrt:x64-uwp cppwinrt:arm-uwp cppwinrt:x86-uwp
seems to triplicate headers. Will later releases refactor them?Install from vcpkg would be very convenience.
https://github.com/Microsoft/vcpkg
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?
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.
I created a library project via UWP/virtual c++, it looks like this:
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 :
Why does it happens? Thank you!
I meet this problem when I want to parse a ValueSet type value, and get the value of it.
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.
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?
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.
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.
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...
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 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.
In this release, how can load and initialize a xaml file?
Reproduction steps: Open XAMLCode sample. In properties, change the platform toolset to Visual Studio 2016 (v41). Compile.
I have attached the error
XamlCode.txt
Is there a way to cast the custom object(inhereted ::IInspectable interface) to winrt::Windows::IInspectable?
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?
I could reproduce the problem by starting from the Blocks sample.
Just add the pch.h file and add the following include:
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 ==========
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.
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.
At the moment, cppwinrt statically links to system librarys (API-MS-WIN-CORE-WINRT-L1-1-0.DLL) that only exist in Win10.
Is it possible to dynamically link all of the necessary dlls?
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?
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.
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);
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.