Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions source/uwp/Renderer/lib/AdaptiveOpenUrlAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ namespace AdaptiveNamespace

ComPtr<IUriRuntimeClassFactory> uriActivationFactory;
RETURN_IF_FAILED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(), &uriActivationFactory));
std::wstring imageUri = StringToWstring(sharedOpenUrlAction->GetUrl());
HString asHstring;
RETURN_IF_FAILED(UTF8ToHString(sharedOpenUrlAction->GetUrl(), asHstring.GetAddressOf()));

if (!imageUri.empty())
if (asHstring.IsValid())
{
RETURN_IF_FAILED(uriActivationFactory->CreateUri(HStringReference(imageUri.c_str()).Get(), m_url.GetAddressOf()));
RETURN_IF_FAILED(uriActivationFactory->CreateUri(asHstring.Get(), m_url.GetAddressOf()));
}

InitializeBaseElement(std::static_pointer_cast<AdaptiveSharedNamespace::BaseActionElement>(sharedOpenUrlAction));
Expand Down
1 change: 0 additions & 1 deletion source/uwp/Renderer/lib/DateTimeParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#pragma once
#include "DateTimePreparser.h"

#include <codecvt>
#include <string>

namespace AdaptiveNamespace
Expand Down
101 changes: 69 additions & 32 deletions source/uwp/Renderer/lib/Util.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include <locale>
#include <codecvt>
#include <string>
#include <regex>

Expand Down Expand Up @@ -54,42 +52,91 @@ using namespace AdaptiveNamespace;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;

HRESULT WStringToHString(const std::wstring& in, _Outptr_ HSTRING* out)
HRESULT WStringToHString(const std::wstring_view& in, _Outptr_ HSTRING* out) noexcept try
{
if (out == nullptr)
{
return E_INVALIDARG;
}
return WindowsCreateString(in.c_str(), static_cast<UINT32>(in.length()), out);
else if (in.empty())
{
return WindowsCreateString(L"", 0, out);
}
else
{
return WindowsCreateString(&in[0], static_cast<UINT32>(in.length()), out);
}
}
CATCH_RETURN;

HRESULT UTF8ToHString(const std::string& in, _Outptr_ HSTRING* out)
std::string WstringToString(const std::wstring_view& in)
{
if (out == nullptr)
if (!in.empty())
{
return E_INVALIDARG;
const size_t requiredSize =
WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, &in[0], (int)in.length(), nullptr, 0, nullptr, nullptr);
std::string converted(requiredSize, 0);

if (WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, &in[0], (int)in.length(), &converted[0], (int)requiredSize, nullptr, nullptr) == 0)
{
throw bad_string_conversion();
}
return converted;
}
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wide = converter.from_bytes(in);
return WindowsCreateString(wide.c_str(), static_cast<UINT32>(wide.length()), out);
return "";
}

HRESULT HStringToUTF8(const HSTRING& in, std::string& out)
std::wstring StringToWstring(const std::string_view& in)
{
if (in == nullptr)
if (!in.empty())
{
// TODO: safer casts
Comment thread
paulcam206 marked this conversation as resolved.
const size_t requiredSize =
MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, &in[0], (int)in.length(), (LPWSTR) nullptr, 0);
std::wstring wide(requiredSize, 0);

if (MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, &in[0], (int)in.length(), &wide[0], (int)requiredSize) == 0)
{
throw bad_string_conversion();
}

return wide;
}
return L"";
}

HRESULT UTF8ToHString(const std::string_view& in, _Outptr_ HSTRING* out) noexcept try
{
if (out == nullptr)
{
return E_INVALIDARG;
}
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
out = converter.to_bytes(WindowsGetStringRawBuffer(in, nullptr));
else
{
std::wstring wide = StringToWstring(in);
return WindowsCreateString(wide.c_str(), static_cast<UINT32>(wide.length()), out);
}
}
CATCH_RETURN;

HRESULT HStringToUTF8(const HSTRING& in, std::string& out) noexcept try
{
out = WstringToString(WindowsGetStringRawBuffer(in, nullptr));
Comment thread
paulcam206 marked this conversation as resolved.
return S_OK;
}
CATCH_RETURN;

std::string HStringToUTF8(const HSTRING& in)
{
std::string typeAsKey;
HRESULT hr = HStringToUTF8(in, typeAsKey);
return FAILED(hr) ? "" : typeAsKey;
if (SUCCEEDED(HStringToUTF8(in, typeAsKey)))
{
return typeAsKey;
}
else
{
return "";
}
}

template<typename TSharedBaseType, typename TAdaptiveBaseType, typename TAdaptiveType>
Expand Down Expand Up @@ -1207,8 +1254,9 @@ CATCH_RETURN;

HRESULT StringToJsonObject(const std::string& inputString, _COM_Outptr_ IJsonObject** result)
{
std::wstring asWstring = StringToWstring(inputString);
return HStringToJsonObject(HStringReference(asWstring.c_str()).Get(), result);
HString asHstring;
RETURN_IF_FAILED(UTF8ToHString(inputString, asHstring.GetAddressOf()));
return HStringToJsonObject(asHstring.Get(), result);
}

HRESULT HStringToJsonObject(const HSTRING& inputHString, _COM_Outptr_ IJsonObject** result)
Expand Down Expand Up @@ -1246,8 +1294,9 @@ HRESULT JsonObjectToHString(_In_ IJsonObject* inputJson, _Outptr_ HSTRING* resul

HRESULT StringToJsonValue(const std::string inputString, _COM_Outptr_ IJsonValue** result)
{
std::wstring asWstring = StringToWstring(inputString);
return HStringToJsonValue(HStringReference(asWstring.c_str()).Get(), result);
HString asHstring;
RETURN_IF_FAILED(UTF8ToHString(inputString, asHstring.GetAddressOf()));
return HStringToJsonValue(asHstring.Get(), result);
}

HRESULT HStringToJsonValue(const HSTRING& inputHString, _COM_Outptr_ IJsonValue** result)
Expand Down Expand Up @@ -1327,18 +1376,6 @@ HRESULT IsBackgroundImageValid(_In_ ABI::AdaptiveNamespace::IAdaptiveBackgroundI
return S_OK;
}

std::wstring StringToWstring(const std::string& in)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> utfConverter;
return utfConverter.from_bytes(in);
}

std::string WstringToString(const std::wstring& input)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> utfConverter;
return utfConverter.to_bytes(input);
}

void RemoteResourceElementToRemoteResourceInformationVector(_In_ ABI::AdaptiveNamespace::IAdaptiveElementWithRemoteResources* remoteResourceElement,
std::vector<RemoteResourceInformation>& resourceUris)
{
Expand Down
23 changes: 16 additions & 7 deletions source/uwp/Renderer/lib/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,33 @@
using namespace InternalNamespace;
#endif

HRESULT WStringToHString(const std::wstring& in, _Outptr_ HSTRING* out);
class bad_string_conversion : public std::exception
{
public:
bad_string_conversion() : _dwErr(GetLastError()) {}

private:
DWORD _dwErr;
};

HRESULT WStringToHString(const std::wstring_view& in, _Outptr_ HSTRING* out) noexcept;

std::string WstringToString(const std::wstring& in);
std::wstring StringToWstring(const std::string& in);
std::string WstringToString(const std::wstring_view& in);
std::wstring StringToWstring(const std::string_view& in);

// This function is needed to deal with the fact that non-windows platforms handle Unicode without the need for wchar_t.
// (which has a platform specific implementation) It converts a std::string to an HSTRING.
HRESULT UTF8ToHString(const std::string& in, _Outptr_ HSTRING* out);
HRESULT UTF8ToHString(const std::string_view& in, _Outptr_ HSTRING* out) noexcept;

// This function is needed to deal with the fact that non-windows platforms handle Unicode without the need for wchar_t.
// (which has a platform specific implementation) It converts from HSTRING to a standard std::string.
HRESULT HStringToUTF8(const HSTRING& in, std::string& out);
HRESULT HStringToUTF8(const HSTRING& in, std::string& out) noexcept;

std::string HStringToUTF8(const HSTRING& in);

inline bool Boolify(const boolean value)
inline bool Boolify(const boolean value) noexcept
{
return value > 0 ? true : false;
return (value > 0);
}

HRESULT GetColorFromString(const std::string& colorString, _Out_ ABI::Windows::UI::Color* color) noexcept;
Expand Down
64 changes: 26 additions & 38 deletions source/uwp/Visualizer/ViewModel/DocumentViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,50 +221,38 @@ public string SerializeActionEventArgsToString(AdaptiveActionEventArgs args)

public static void InitializeRenderer(AdaptiveHostConfig hostConfig)
{
try
_renderer = new AdaptiveCardRenderer();
if (hostConfig != null)
{
_renderer = new AdaptiveCardRenderer();
if (hostConfig != null)
{
_renderer.HostConfig = hostConfig;
}

// Add a feature representing this version of the visualizer. used for test cards.
_renderer.FeatureRegistration.Set("acTest", "1.0");
_renderer.HostConfig = hostConfig;
}

if (Settings.UseFixedDimensions)
{
_renderer.SetFixedDimensions(320, 180);
}
// Add a feature representing this version of the visualizer. used for test cards.
_renderer.FeatureRegistration.Set("acTest", "1.0");

// Custom resource resolvers
_renderer.ResourceResolvers.Set("symbol", new MySymbolResourceResolver());
if (Settings.UseFixedDimensions)
{
_renderer.SetFixedDimensions(320, 180);
}

/*
*Example on how to override the Action Positive and Destructive styles
Style positiveStyle = new Style(typeof(Button));
positiveStyle.Setters.Add(new Setter(Button.BackgroundProperty, new SolidColorBrush(Windows.UI.Colors.LawnGreen)));
Style destructiveStyle = new Style(typeof(Button));
destructiveStyle.Setters.Add(new Setter(Button.BackgroundProperty, new SolidColorBrush(Windows.UI.Colors.Red)));
Style otherStyle = new Style(typeof(Button));
otherStyle.Setters.Add(new Setter(Button.BackgroundProperty, new SolidColorBrush(Windows.UI.Colors.Yellow)));
otherStyle.Setters.Add(new Setter(Button.ForegroundProperty, new SolidColorBrush(Windows.UI.Colors.DarkRed)));
// Custom resource resolvers
_renderer.ResourceResolvers.Set("symbol", new MySymbolResourceResolver());

_renderer.OverrideStyles = new ResourceDictionary();
_renderer.OverrideStyles.Add("Adaptive.Action.Positive", positiveStyle);
_renderer.OverrideStyles.Add("Adaptive.Action.Destructive", destructiveStyle);
_renderer.OverrideStyles.Add("Adaptive.Action.other", otherStyle);
*/
/*
*Example on how to override the Action Positive and Destructive styles
Style positiveStyle = new Style(typeof(Button));
positiveStyle.Setters.Add(new Setter(Button.BackgroundProperty, new SolidColorBrush(Windows.UI.Colors.LawnGreen)));
Style destructiveStyle = new Style(typeof(Button));
destructiveStyle.Setters.Add(new Setter(Button.BackgroundProperty, new SolidColorBrush(Windows.UI.Colors.Red)));
Style otherStyle = new Style(typeof(Button));
otherStyle.Setters.Add(new Setter(Button.BackgroundProperty, new SolidColorBrush(Windows.UI.Colors.Yellow)));
otherStyle.Setters.Add(new Setter(Button.ForegroundProperty, new SolidColorBrush(Windows.UI.Colors.DarkRed)));

}
catch
{
if (Debugger.IsAttached)
{
Debugger.Break();
}
throw;
}
_renderer.OverrideStyles = new ResourceDictionary();
_renderer.OverrideStyles.Add("Adaptive.Action.Positive", positiveStyle);
_renderer.OverrideStyles.Add("Adaptive.Action.Destructive", destructiveStyle);
_renderer.OverrideStyles.Add("Adaptive.Action.other", otherStyle);
*/
}
}
}