Fix the project code style, as it is not consistent. (#236)

Fixes #202
This PR fixes code style for the project files.

The Problem
Different files in the project use different code style. That is not consistent and leads to harder maintenance of the project.

Description of the changes:
Have investigated and determined the most used code style across the given codebase
Have configured IDE and applied code style to all project files.
Have crafted clang-formatter config.
see https://clang.llvm.org/docs/ClangFormat.html
https://clang.llvm.org/docs/ClangFormatStyleOptions.html
Some cases were fixed manually
How changes were validated:
manual/ad-hoc testing, automated testing

All tests pass as before because these are only code style changes.
Additional
Please review, and let me know if I have any mistake in the code style. In case of any mistake, I will change the configuration and re-apply it to the project.
This commit is contained in:
Oleg Abrazhaev
2019-05-02 20:59:19 +02:00
committed by Daniel Belcher
parent c77f1de84c
commit 2826d37056
237 changed files with 12824 additions and 11843 deletions

View File

@@ -3,107 +3,102 @@
#pragma once
namespace CalculatorApp { namespace Common
namespace CalculatorApp
{
ref class AlwaysSelectedCollectionView sealed:
public Windows::UI::Xaml::DependencyObject,
public Windows::UI::Xaml::Data::ICollectionView
namespace Common
{
internal:
AlwaysSelectedCollectionView(Windows::UI::Xaml::Interop::IBindableVector^ source):
m_currentPosition(-1)
ref class AlwaysSelectedCollectionView sealed : public Windows::UI::Xaml::DependencyObject, public Windows::UI::Xaml::Data::ICollectionView
{
m_source = source;
internal : AlwaysSelectedCollectionView(Windows::UI::Xaml::Interop::IBindableVector ^ source) : m_currentPosition(-1)
{
m_source = source;
Windows::UI::Xaml::Interop::IBindableObservableVector^ observable = dynamic_cast<Windows::UI::Xaml::Interop::IBindableObservableVector^>(source);
if (observable)
{
observable->VectorChanged +=
ref new Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler(this, &AlwaysSelectedCollectionView::OnSourceBindableVectorChanged);
}
}
private:
// ICollectionView
// Not implemented methods
virtual WF::IAsyncOperation<Windows::UI::Xaml::Data::LoadMoreItemsResult>^ LoadMoreItemsAsync(unsigned int) = Windows::UI::Xaml::Data::ICollectionView::LoadMoreItemsAsync
{
throw ref new Platform::NotImplementedException();
}
virtual bool MoveCurrentToFirst() = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToFirst
{
throw ref new Platform::NotImplementedException();
}
virtual bool MoveCurrentToLast() = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToLast
{
throw ref new Platform::NotImplementedException();
}
virtual bool MoveCurrentToNext() = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToNext
{
throw ref new Platform::NotImplementedException();
}
virtual bool MoveCurrentToPrevious() = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToPrevious
{
throw ref new Platform::NotImplementedException();
}
property Windows::Foundation::Collections::IObservableVector<Platform::Object^>^ CollectionGroups
{
virtual Windows::Foundation::Collections::IObservableVector<Platform::Object^>^ get() = Windows::UI::Xaml::Data::ICollectionView::CollectionGroups::get
{
return ref new Platform::Collections::Vector<Platform::Object^>();
}
}
property bool HasMoreItems
{
virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::HasMoreItems::get
{
return false;
}
}
// Implemented methods
virtual bool MoveCurrentTo(Platform::Object^ item) = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentTo
{
if (item)
{
unsigned int newCurrentPosition = 0;
bool result = m_source->IndexOf(item, &newCurrentPosition);
if (result)
Windows::UI::Xaml::Interop::IBindableObservableVector ^ observable =
dynamic_cast<Windows::UI::Xaml::Interop::IBindableObservableVector ^>(source);
if (observable)
{
m_currentPosition = newCurrentPosition;
m_currentChanged(this, nullptr);
return true;
observable->VectorChanged += ref new Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler(
this, &AlwaysSelectedCollectionView::OnSourceBindableVectorChanged);
}
}
// The item is not in the collection
// We're going to schedule a call back later so we
// restore the selection to the way we wanted it to begin with
if (m_currentPosition >= 0 && m_currentPosition < static_cast<int>(m_source->Size))
private:
// ICollectionView
// Not implemented methods
virtual WF::IAsyncOperation<
Windows::UI::Xaml::Data::LoadMoreItemsResult> ^ LoadMoreItemsAsync(unsigned int) = Windows::UI::Xaml::Data::ICollectionView::LoadMoreItemsAsync
{
this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler(
[this]()
{
m_currentChanged(this, nullptr);
}));
throw ref new Platform::NotImplementedException();
}
return false;
}
virtual bool MoveCurrentToPosition(int index) = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToPosition
{
if (index < 0 || index >= static_cast<int>(m_source->Size))
virtual bool MoveCurrentToFirst() = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToFirst
{
throw ref new Platform::NotImplementedException();
}
virtual bool MoveCurrentToLast() = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToLast
{
throw ref new Platform::NotImplementedException();
}
virtual bool MoveCurrentToNext() = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToNext
{
throw ref new Platform::NotImplementedException();
}
virtual bool MoveCurrentToPrevious() = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToPrevious
{
throw ref new Platform::NotImplementedException();
}
property Windows::Foundation::Collections::IObservableVector<Platform::Object ^> ^ CollectionGroups {
virtual Windows::Foundation::Collections::IObservableVector<Platform::Object
^> ^ get() = Windows::UI::Xaml::Data::ICollectionView::CollectionGroups::get
{
return ref new Platform::Collections::Vector<Platform::Object ^>();
}
} property bool HasMoreItems
{
virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::HasMoreItems::get
{
return false;
}
}
// Implemented methods
virtual bool MoveCurrentTo(Platform::Object ^ item) = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentTo
{
if (item)
{
unsigned int newCurrentPosition = 0;
bool result = m_source->IndexOf(item, &newCurrentPosition);
if (result)
{
m_currentPosition = newCurrentPosition;
m_currentChanged(this, nullptr);
return true;
}
}
// The item is not in the collection
// We're going to schedule a call back later so we
// restore the selection to the way we wanted it to begin with
if (m_currentPosition >= 0 && m_currentPosition < static_cast<int>(m_source->Size))
{
this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this]() { m_currentChanged(this, nullptr); }));
}
return false;
}
m_currentPosition = index;
m_currentChanged(this, nullptr);
return true;
}
virtual bool MoveCurrentToPosition(int index) = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToPosition
{
if (index < 0 || index >= static_cast<int>(m_source->Size))
{
return false;
}
property Platform::Object^ CurrentItem
m_currentPosition = index;
m_currentChanged(this, nullptr);
return true;
}
property Platform::Object^ CurrentItem
{
virtual Platform::Object^ get() = Windows::UI::Xaml::Data::ICollectionView::CurrentItem::get
{
@@ -116,30 +111,30 @@ namespace CalculatorApp { namespace Common
}
property int CurrentPosition
{
virtual int get() = Windows::UI::Xaml::Data::ICollectionView::CurrentPosition::get
{
return m_currentPosition;
virtual int get() = Windows::UI::Xaml::Data::ICollectionView::CurrentPosition::get
{
return m_currentPosition;
}
}
}
property bool IsCurrentAfterLast
{
virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::IsCurrentAfterLast::get
property bool IsCurrentAfterLast
{
return m_currentPosition >= static_cast<int>(m_source->Size);
virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::IsCurrentAfterLast::get
{
return m_currentPosition >= static_cast<int>(m_source->Size);
}
}
}
property bool IsCurrentBeforeFirst
{
virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::IsCurrentBeforeFirst::get
property bool IsCurrentBeforeFirst
{
return m_currentPosition < 0;
virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::IsCurrentBeforeFirst::get
{
return m_currentPosition < 0;
}
}
}
event WF::EventHandler<Platform::Object^>^ CurrentChanged
event WF::EventHandler<Platform::Object^>^ CurrentChanged
{
virtual WF::EventRegistrationToken add(WF::EventHandler<Platform::Object^>^ handler) = Windows::UI::Xaml::Data::ICollectionView::CurrentChanged::add
{
@@ -165,63 +160,67 @@ namespace CalculatorApp { namespace Common
// IVector<Object^>
// Not implemented methods
virtual void Append(Platform::Object^ /*item*/) = Windows::Foundation::Collections::IVector<Platform::Object^>::Append
{
throw ref new Platform::NotImplementedException();
}
virtual void Clear() = Windows::Foundation::Collections::IVector<Platform::Object^>::Clear
{
throw ref new Platform::NotImplementedException();
}
virtual unsigned int GetMany(unsigned int /*startIndex*/, Platform::WriteOnlyArray<Platform::Object^>^ /*items*/) = Windows::Foundation::Collections::IVector<Platform::Object^>::GetMany
{
throw ref new Platform::NotImplementedException();
}
virtual Windows::Foundation::Collections::IVectorView<Platform::Object^>^ GetView() = Windows::Foundation::Collections::IVector<Platform::Object^>::GetView
{
throw ref new Platform::NotImplementedException();
}
virtual void InsertAt(unsigned int /*index*/, Platform::Object^ /*item*/) = Windows::Foundation::Collections::IVector<Platform::Object^>::InsertAt
{
throw ref new Platform::NotImplementedException();
}
virtual void RemoveAt(unsigned int /*index*/) = Windows::Foundation::Collections::IVector<Platform::Object^>::RemoveAt
{
throw ref new Platform::NotImplementedException();
}
virtual void RemoveAtEnd() = Windows::Foundation::Collections::IVector<Platform::Object^>::RemoveAtEnd
{
throw ref new Platform::NotImplementedException();
}
virtual void ReplaceAll(const Platform::Array<Platform::Object^>^ /*items*/) = Windows::Foundation::Collections::IVector<Platform::Object^>::ReplaceAll
{
throw ref new Platform::NotImplementedException();
}
virtual void SetAt(unsigned int /*index*/, Platform::Object^ /*item*/) = Windows::Foundation::Collections::IVector<Platform::Object^>::SetAt
{
throw ref new Platform::NotImplementedException();
}
// Implemented methods
virtual Platform::Object^ GetAt(unsigned int index) = Windows::Foundation::Collections::IVector<Platform::Object^>::GetAt
{
return m_source->GetAt(index);
}
virtual bool IndexOf(Platform::Object^ item, unsigned int* index) = Windows::Foundation::Collections::IVector<Platform::Object^>::IndexOf
{
return m_source->IndexOf(item, index);
}
property unsigned int Size
{
virtual unsigned int get() = Windows::Foundation::Collections::IVector<Platform::Object^>::Size::get
{
return m_source->Size;
throw ref new Platform::NotImplementedException();
}
virtual void Clear() = Windows::Foundation::Collections::IVector<Platform::Object ^>::Clear
{
throw ref new Platform::NotImplementedException();
}
virtual unsigned int
GetMany(unsigned int /*startIndex*/,
Platform::WriteOnlyArray<Platform::Object ^> ^ /*items*/) = Windows::Foundation::Collections::IVector<Platform::Object ^>::GetMany
{
throw ref new Platform::NotImplementedException();
}
virtual Windows::Foundation::Collections::IVectorView<Platform::Object ^> ^ GetView() = Windows::Foundation::Collections::IVector<Platform::Object
^>::GetView
{
throw ref new Platform::NotImplementedException();
}
virtual void InsertAt(unsigned int /*index*/, Platform::Object ^ /*item*/) = Windows::Foundation::Collections::IVector<Platform::Object ^>::InsertAt
{
throw ref new Platform::NotImplementedException();
}
virtual void RemoveAt(unsigned int /*index*/) = Windows::Foundation::Collections::IVector<Platform::Object ^>::RemoveAt
{
throw ref new Platform::NotImplementedException();
}
virtual void RemoveAtEnd() = Windows::Foundation::Collections::IVector<Platform::Object ^>::RemoveAtEnd
{
throw ref new Platform::NotImplementedException();
}
virtual void
ReplaceAll(const Platform::Array<Platform::Object ^> ^ /*items*/) = Windows::Foundation::Collections::IVector<Platform::Object ^>::ReplaceAll
{
throw ref new Platform::NotImplementedException();
}
virtual void SetAt(unsigned int /*index*/, Platform::Object ^ /*item*/) = Windows::Foundation::Collections::IVector<Platform::Object ^>::SetAt
{
throw ref new Platform::NotImplementedException();
}
}
// IObservableVector<Object^>
event Windows::Foundation::Collections::VectorChangedEventHandler<Platform::Object^>^ VectorChanged
// Implemented methods
virtual Platform::Object ^ GetAt(unsigned int index) = Windows::Foundation::Collections::IVector<Platform::Object ^>::GetAt
{
return m_source->GetAt(index);
}
virtual bool IndexOf(Platform::Object ^ item, unsigned int* index) = Windows::Foundation::Collections::IVector<Platform::Object ^>::IndexOf
{
return m_source->IndexOf(item, index);
}
property unsigned int Size
{
virtual unsigned int get() = Windows::Foundation::Collections::IVector<Platform::Object ^>::Size::get
{
return m_source->Size;
}
}
// IObservableVector<Object^>
event Windows::Foundation::Collections::VectorChangedEventHandler<Platform::Object^>^ VectorChanged
{
virtual WF::EventRegistrationToken add(Windows::Foundation::Collections::VectorChangedEventHandler<Platform::Object^>^ handler) = Windows::Foundation::Collections::IObservableVector<Platform::Object^>::VectorChanged::add
{
@@ -236,52 +235,51 @@ namespace CalculatorApp { namespace Common
// IIterable<Object^>
// Not implemented
virtual Windows::Foundation::Collections::IIterator<Platform::Object^>^ First() = Windows::Foundation::Collections::IIterable<Platform::Object^>::First
{
throw ref new Platform::NotImplementedException();
}
// Event handlers
void OnSourceBindableVectorChanged(Windows::UI::Xaml::Interop::IBindableObservableVector^ source, Platform::Object^ e)
{
Windows::Foundation::Collections::IVectorChangedEventArgs^ args = safe_cast<Windows::Foundation::Collections::IVectorChangedEventArgs^>(e);
m_vectorChanged(this, args);
}
Windows::UI::Xaml::Interop::IBindableVector^ m_source;
int m_currentPosition;
event WF::EventHandler<Platform::Object^>^ m_currentChanged;
event Windows::UI::Xaml::Data::CurrentChangingEventHandler^ m_currentChanging;
event Windows::Foundation::Collections::VectorChangedEventHandler<Platform::Object^>^ m_vectorChanged;
};
public ref class AlwaysSelectedCollectionViewConverter sealed: public Windows::UI::Xaml::Data::IValueConverter
{
public:
AlwaysSelectedCollectionViewConverter()
{ }
private:
virtual Platform::Object^ Convert(
Platform::Object^ value,
Windows::UI::Xaml::Interop::TypeName /*targetType*/,
Platform::Object^ /*parameter*/,
Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert
{
auto result = dynamic_cast<Windows::UI::Xaml::Interop::IBindableVector^>(value);
if (result)
{
return ref new AlwaysSelectedCollectionView(result);
throw ref new Platform::NotImplementedException();
}
return Windows::UI::Xaml::DependencyProperty::UnsetValue; // Can't convert
}
virtual Platform::Object^ ConvertBack(
Platform::Object^ /*value*/,
Windows::UI::Xaml::Interop::TypeName /*targetType*/,
Platform::Object^ /*parameter*/,
Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack
// Event handlers
void OnSourceBindableVectorChanged(Windows::UI::Xaml::Interop::IBindableObservableVector ^ source, Platform::Object ^ e)
{
Windows::Foundation::Collections::IVectorChangedEventArgs ^ args = safe_cast<Windows::Foundation::Collections::IVectorChangedEventArgs ^>(e);
m_vectorChanged(this, args);
}
Windows::UI::Xaml::Interop::IBindableVector ^ m_source;
int m_currentPosition;
event WF::EventHandler<Platform::Object ^> ^ m_currentChanged;
event Windows::UI::Xaml::Data::CurrentChangingEventHandler ^ m_currentChanging;
event Windows::Foundation::Collections::VectorChangedEventHandler<Platform::Object ^> ^ m_vectorChanged;
};
public
ref class AlwaysSelectedCollectionViewConverter sealed : public Windows::UI::Xaml::Data::IValueConverter
{
return Windows::UI::Xaml::DependencyProperty::UnsetValue;
}
};
}}
public:
AlwaysSelectedCollectionViewConverter()
{
}
private:
virtual Platform::Object
^ Convert(Platform::Object ^ value, Windows::UI::Xaml::Interop::TypeName /*targetType*/, Platform::Object ^ /*parameter*/,
Platform::String ^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert
{
auto result = dynamic_cast<Windows::UI::Xaml::Interop::IBindableVector ^>(value);
if (result)
{
return ref new AlwaysSelectedCollectionView(result);
}
return Windows::UI::Xaml::DependencyProperty::UnsetValue; // Can't convert
}
virtual Platform::Object
^ ConvertBack(Platform::Object ^ /*value*/, Windows::UI::Xaml::Interop::TypeName /*targetType*/, Platform::Object ^ /*parameter*/,
Platform::String ^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack
{
return Windows::UI::Xaml::DependencyProperty::UnsetValue;
}
};
}
}

View File

@@ -14,18 +14,18 @@ AppResourceProvider::AppResourceProvider()
m_cEngineStringResLoader = ResourceLoader::GetForViewIndependentUse(L"CEngineStrings");
}
AppResourceProvider & AppResourceProvider::GetInstance()
AppResourceProvider& AppResourceProvider::GetInstance()
{
static AppResourceProvider s_instance;
return s_instance;
}
String^ AppResourceProvider::GetResourceString(_In_ String^ key)
String ^ AppResourceProvider::GetResourceString(_In_ String ^ key)
{
return m_stringResLoader->GetString(key);
}
String^ AppResourceProvider::GetCEngineString(_In_ String^ key)
String ^ AppResourceProvider::GetCEngineString(_In_ String ^ key)
{
return m_cEngineStringResLoader->GetString(key);
}

View File

@@ -8,13 +8,13 @@ namespace CalculatorApp
class AppResourceProvider
{
public:
static AppResourceProvider & GetInstance();
Platform::String^ GetResourceString(_In_ Platform::String^ key);
Platform::String^ GetCEngineString(_In_ Platform::String^ key);
static AppResourceProvider& GetInstance();
Platform::String ^ GetResourceString(_In_ Platform::String ^ key);
Platform::String ^ GetCEngineString(_In_ Platform::String ^ key);
private:
AppResourceProvider();
Windows::ApplicationModel::Resources::ResourceLoader^ m_stringResLoader;
Windows::ApplicationModel::Resources::ResourceLoader^ m_cEngineStringResLoader;
Windows::ApplicationModel::Resources::ResourceLoader ^ m_stringResLoader;
Windows::ApplicationModel::Resources::ResourceLoader ^ m_cEngineStringResLoader;
};
}

View File

@@ -11,16 +11,17 @@
namespace CalculatorApp::Common::Automation
{
public interface class INarratorAnnouncementHost
public
interface class INarratorAnnouncementHost
{
public:
// Is the host available on this OS.
bool IsHostAvailable();
// Make a new instance of a concrete host.
INarratorAnnouncementHost^ MakeHost();
INarratorAnnouncementHost ^ MakeHost();
// Make an announcement using the concrete host's preferred method.
void Announce(NarratorAnnouncement^ announcement);
void Announce(NarratorAnnouncement ^ announcement);
};
}

View File

@@ -9,9 +9,9 @@ using namespace Windows::UI::Xaml::Automation;
using namespace Windows::UI::Xaml::Automation::Peers;
using namespace Windows::UI::Xaml::Controls;
LiveRegionHost::LiveRegionHost() :
m_host(nullptr)
{}
LiveRegionHost::LiveRegionHost() : m_host(nullptr)
{
}
bool LiveRegionHost::IsHostAvailable()
{
@@ -19,12 +19,12 @@ bool LiveRegionHost::IsHostAvailable()
return true;
}
INarratorAnnouncementHost^ LiveRegionHost::MakeHost()
INarratorAnnouncementHost ^ LiveRegionHost::MakeHost()
{
return ref new LiveRegionHost();
}
void LiveRegionHost::Announce(NarratorAnnouncement^ announcement)
void LiveRegionHost::Announce(NarratorAnnouncement ^ announcement)
{
if (m_host == nullptr)
{
@@ -33,7 +33,7 @@ void LiveRegionHost::Announce(NarratorAnnouncement^ announcement)
}
AutomationProperties::SetName(m_host, announcement->Announcement);
AutomationPeer^ peer = FrameworkElementAutomationPeer::FromElement(m_host);
AutomationPeer ^ peer = FrameworkElementAutomationPeer::FromElement(m_host);
if (peer != nullptr)
{
peer->RaiseAutomationEvent(AutomationEvents::LiveRegionChanged);

View File

@@ -16,17 +16,18 @@ namespace CalculatorApp::Common::Automation
// When the app switches to min version RS3, this class can be removed
// and the app will switch to using the Notification API.
// TODO - MSFT 12735088
public ref class LiveRegionHost sealed : public INarratorAnnouncementHost
public
ref class LiveRegionHost sealed : public INarratorAnnouncementHost
{
public:
LiveRegionHost();
virtual bool IsHostAvailable();
virtual INarratorAnnouncementHost^ MakeHost();
virtual INarratorAnnouncementHost ^ MakeHost();
virtual void Announce(NarratorAnnouncement^ announcement);
virtual void Announce(NarratorAnnouncement ^ announcement);
private:
Windows::UI::Xaml::UIElement^ m_host;
Windows::UI::Xaml::UIElement ^ m_host;
};
}

View File

@@ -25,24 +25,18 @@ namespace CalculatorApp::Common::Automation
}
}
NarratorAnnouncement::NarratorAnnouncement(
String^ announcement,
String^ activityId,
AutomationNotificationKind kind,
AutomationNotificationProcessing processing)
:
m_announcement(announcement),
m_activityId(activityId),
m_kind(kind),
m_processing(processing)
{}
NarratorAnnouncement::NarratorAnnouncement(String ^ announcement, String ^ activityId, AutomationNotificationKind kind,
AutomationNotificationProcessing processing)
: m_announcement(announcement), m_activityId(activityId), m_kind(kind), m_processing(processing)
{
}
String^ NarratorAnnouncement::Announcement::get()
String ^ NarratorAnnouncement::Announcement::get()
{
return m_announcement;
}
String^ NarratorAnnouncement::ActivityId::get()
String ^ NarratorAnnouncement::ActivityId::get()
{
return m_activityId;
}
@@ -57,108 +51,73 @@ AutomationNotificationProcessing NarratorAnnouncement::Processing::get()
return m_processing;
}
bool NarratorAnnouncement::IsValid(NarratorAnnouncement^ announcement)
bool NarratorAnnouncement::IsValid(NarratorAnnouncement ^ announcement)
{
return announcement != nullptr
&& announcement->Announcement != nullptr
&& !announcement->Announcement->IsEmpty();
return announcement != nullptr && announcement->Announcement != nullptr && !announcement->Announcement->IsEmpty();
}
NarratorAnnouncement^ CalculatorAnnouncement::GetDisplayUpdatedAnnouncement(String^ announcement)
NarratorAnnouncement ^ CalculatorAnnouncement::GetDisplayUpdatedAnnouncement(String ^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::DisplayUpdated,
AutomationNotificationKind::Other,
AutomationNotificationProcessing::ImportantMostRecent);
return ref new NarratorAnnouncement(announcement, CalculatorActivityIds::DisplayUpdated, AutomationNotificationKind::Other,
AutomationNotificationProcessing::ImportantMostRecent);
}
NarratorAnnouncement^ CalculatorAnnouncement::GetMaxDigitsReachedAnnouncement(String^ announcement)
NarratorAnnouncement ^ CalculatorAnnouncement::GetMaxDigitsReachedAnnouncement(String ^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::MaxDigitsReached,
AutomationNotificationKind::Other,
AutomationNotificationProcessing::ImportantMostRecent);
return ref new NarratorAnnouncement(announcement, CalculatorActivityIds::MaxDigitsReached, AutomationNotificationKind::Other,
AutomationNotificationProcessing::ImportantMostRecent);
}
NarratorAnnouncement^ CalculatorAnnouncement::GetMemoryClearedAnnouncement(String^ announcement)
NarratorAnnouncement ^ CalculatorAnnouncement::GetMemoryClearedAnnouncement(String ^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::MemoryCleared,
AutomationNotificationKind::ItemRemoved,
AutomationNotificationProcessing::ImportantMostRecent);
return ref new NarratorAnnouncement(announcement, CalculatorActivityIds::MemoryCleared, AutomationNotificationKind::ItemRemoved,
AutomationNotificationProcessing::ImportantMostRecent);
}
NarratorAnnouncement^ CalculatorAnnouncement::GetMemoryItemChangedAnnouncement(String^ announcement)
NarratorAnnouncement ^ CalculatorAnnouncement::GetMemoryItemChangedAnnouncement(String ^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::MemoryItemChanged,
AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::MostRecent);
return ref new NarratorAnnouncement(announcement, CalculatorActivityIds::MemoryItemChanged, AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::MostRecent);
}
NarratorAnnouncement^ CalculatorAnnouncement::GetMemoryItemAddedAnnouncement(String^ announcement)
NarratorAnnouncement ^ CalculatorAnnouncement::GetMemoryItemAddedAnnouncement(String ^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::MemoryItemAdded,
AutomationNotificationKind::ItemAdded,
AutomationNotificationProcessing::MostRecent);
return ref new NarratorAnnouncement(announcement, CalculatorActivityIds::MemoryItemAdded, AutomationNotificationKind::ItemAdded,
AutomationNotificationProcessing::MostRecent);
}
NarratorAnnouncement^ CalculatorAnnouncement::GetHistoryClearedAnnouncement(String^ announcement)
NarratorAnnouncement ^ CalculatorAnnouncement::GetHistoryClearedAnnouncement(String ^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::HistoryCleared,
AutomationNotificationKind::ItemRemoved,
AutomationNotificationProcessing::MostRecent);
return ref new NarratorAnnouncement(announcement, CalculatorActivityIds::HistoryCleared, AutomationNotificationKind::ItemRemoved,
AutomationNotificationProcessing::MostRecent);
}
NarratorAnnouncement^ CalculatorAnnouncement::GetCategoryNameChangedAnnouncement(String^ announcement)
NarratorAnnouncement ^ CalculatorAnnouncement::GetCategoryNameChangedAnnouncement(String ^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::CategoryNameChanged,
AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
return ref new NarratorAnnouncement(announcement, CalculatorActivityIds::CategoryNameChanged, AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
}
NarratorAnnouncement^ CalculatorAnnouncement::GetUpdateCurrencyRatesAnnouncement(String^ announcement)
NarratorAnnouncement ^ CalculatorAnnouncement::GetUpdateCurrencyRatesAnnouncement(String ^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::UpdateCurrencyRates,
AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
return ref new NarratorAnnouncement(announcement, CalculatorActivityIds::UpdateCurrencyRates, AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
}
NarratorAnnouncement^ CalculatorAnnouncement::GetDisplayCopiedAnnouncement(String^ announcement)
NarratorAnnouncement ^ CalculatorAnnouncement::GetDisplayCopiedAnnouncement(String ^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::DisplayCopied,
AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
return ref new NarratorAnnouncement(announcement, CalculatorActivityIds::DisplayCopied, AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
}
NarratorAnnouncement^ CalculatorAnnouncement::GetOpenParenthesisCountChangedAnnouncement(String^ announcement)
NarratorAnnouncement ^ CalculatorAnnouncement::GetOpenParenthesisCountChangedAnnouncement(String ^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::OpenParenthesisCountChanged,
AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
return ref new NarratorAnnouncement(announcement, CalculatorActivityIds::OpenParenthesisCountChanged, AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
}
NarratorAnnouncement^ CalculatorAnnouncement::GetNoRightParenthesisAddedAnnouncement(String^ announcement)
NarratorAnnouncement ^ CalculatorAnnouncement::GetNoRightParenthesisAddedAnnouncement(String ^ announcement)
{
return ref new NarratorAnnouncement(
announcement,
CalculatorActivityIds::NoParenthesisAdded,
AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
return ref new NarratorAnnouncement(announcement, CalculatorActivityIds::NoParenthesisAdded, AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::ImportantMostRecent);
}

View File

@@ -11,7 +11,8 @@ namespace CalculatorApp::Common::Automation
// enums should be removed and the Windows types should be used
// instead.
// TODO - MSFT 12735088
public enum class AutomationNotificationKind
public
enum class AutomationNotificationKind
{
ItemAdded = 0,
ItemRemoved = 1,
@@ -20,7 +21,8 @@ namespace CalculatorApp::Common::Automation
Other = 4
};
public enum class AutomationNotificationProcessing
public
enum class AutomationNotificationProcessing
{
ImportantAll = 0,
ImportantMostRecent = 1,
@@ -29,20 +31,17 @@ namespace CalculatorApp::Common::Automation
CurrentThenMostRecent = 4
};
public ref class NarratorAnnouncement sealed
public
ref class NarratorAnnouncement sealed
{
public:
property Platform::String^ Announcement
{
Platform::String^ get();
}
property Platform::String
^ Announcement { Platform::String ^ get(); }
property Platform::String^ ActivityId
{
Platform::String^ get();
}
property Platform::String
^ ActivityId { Platform::String ^ get(); }
property AutomationNotificationKind Kind
property AutomationNotificationKind Kind
{
AutomationNotificationKind get();
}
@@ -52,21 +51,18 @@ namespace CalculatorApp::Common::Automation
AutomationNotificationProcessing get();
}
static bool IsValid(NarratorAnnouncement^ announcement);
static bool IsValid(NarratorAnnouncement ^ announcement);
private:
// Make CalculatorAnnouncement a friend class so it is the only
// class that can access the private constructor.
friend class CalculatorAnnouncement;
NarratorAnnouncement(
Platform::String^ announcement,
Platform::String^ activityId,
AutomationNotificationKind kind,
AutomationNotificationProcessing processing);
NarratorAnnouncement(Platform::String ^ announcement, Platform::String ^ activityId, AutomationNotificationKind kind,
AutomationNotificationProcessing processing);
Platform::String^ m_announcement;
Platform::String^ m_activityId;
Platform::String ^ m_announcement;
Platform::String ^ m_activityId;
AutomationNotificationKind m_kind;
AutomationNotificationProcessing m_processing;
};
@@ -76,22 +72,22 @@ namespace CalculatorApp::Common::Automation
class CalculatorAnnouncement
{
public:
static NarratorAnnouncement^ GetDisplayUpdatedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement^ GetMaxDigitsReachedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement ^ GetDisplayUpdatedAnnouncement(Platform::String ^ announcement);
static NarratorAnnouncement ^ GetMaxDigitsReachedAnnouncement(Platform::String ^ announcement);
static NarratorAnnouncement^ GetMemoryClearedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement^ GetMemoryItemChangedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement^ GetMemoryItemAddedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement ^ GetMemoryClearedAnnouncement(Platform::String ^ announcement);
static NarratorAnnouncement ^ GetMemoryItemChangedAnnouncement(Platform::String ^ announcement);
static NarratorAnnouncement ^ GetMemoryItemAddedAnnouncement(Platform::String ^ announcement);
static NarratorAnnouncement^ GetHistoryClearedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement ^ GetHistoryClearedAnnouncement(Platform::String ^ announcement);
static NarratorAnnouncement^ GetCategoryNameChangedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement ^ GetCategoryNameChangedAnnouncement(Platform::String ^ announcement);
static NarratorAnnouncement^ GetUpdateCurrencyRatesAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement ^ GetUpdateCurrencyRatesAnnouncement(Platform::String ^ announcement);
static NarratorAnnouncement^ GetDisplayCopiedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement ^ GetDisplayCopiedAnnouncement(Platform::String ^ announcement);
static NarratorAnnouncement^ GetOpenParenthesisCountChangedAnnouncement(Platform::String^ announcement);
static NarratorAnnouncement^ GetNoRightParenthesisAddedAnnouncement(Platform::String ^ announcement);
static NarratorAnnouncement ^ GetOpenParenthesisCountChangedAnnouncement(Platform::String ^ announcement);
static NarratorAnnouncement ^ GetNoRightParenthesisAddedAnnouncement(Platform::String ^ announcement);
};
}

View File

@@ -9,8 +9,8 @@
using namespace CalculatorApp::Common::Automation;
using namespace std;
INarratorAnnouncementHost^ NarratorAnnouncementHostFactory::s_hostProducer;
vector<INarratorAnnouncementHost^> NarratorAnnouncementHostFactory::s_hosts;
INarratorAnnouncementHost ^ NarratorAnnouncementHostFactory::s_hostProducer;
vector<INarratorAnnouncementHost ^> NarratorAnnouncementHostFactory::s_hosts;
// This static variable is used only to call the initialization function, to initialize the other static variables.
int NarratorAnnouncementHostFactory::s_init = NarratorAnnouncementHostFactory::Initialize();
@@ -32,15 +32,12 @@ void NarratorAnnouncementHostFactory::RegisterHosts()
{
// The host that will be used is the first available host,
// therefore, order of hosts is important here.
NarratorAnnouncementHostFactory::s_hosts = {
ref new NotificationHost(),
ref new LiveRegionHost()
};
NarratorAnnouncementHostFactory::s_hosts = { ref new NotificationHost(), ref new LiveRegionHost() };
}
INarratorAnnouncementHost^ NarratorAnnouncementHostFactory::GetHostProducer()
INarratorAnnouncementHost ^ NarratorAnnouncementHostFactory::GetHostProducer()
{
for (INarratorAnnouncementHost^ host : NarratorAnnouncementHostFactory::s_hosts)
for (INarratorAnnouncementHost ^ host : NarratorAnnouncementHostFactory::s_hosts)
{
if (host->IsHostAvailable())
{
@@ -52,7 +49,7 @@ INarratorAnnouncementHost^ NarratorAnnouncementHostFactory::GetHostProducer()
return nullptr;
}
INarratorAnnouncementHost^ NarratorAnnouncementHostFactory::MakeHost()
INarratorAnnouncementHost ^ NarratorAnnouncementHostFactory::MakeHost()
{
if (NarratorAnnouncementHostFactory::s_hostProducer == nullptr)
{

View File

@@ -14,18 +14,20 @@ namespace CalculatorApp::Common::Automation
class NarratorAnnouncementHostFactory
{
public:
static INarratorAnnouncementHost^ MakeHost();
static INarratorAnnouncementHost ^ MakeHost();
private:
NarratorAnnouncementHostFactory() {}
NarratorAnnouncementHostFactory()
{
}
static int Initialize();
static void RegisterHosts();
static INarratorAnnouncementHost^ GetHostProducer();
static INarratorAnnouncementHost ^ GetHostProducer();
private:
static int s_init;
static INarratorAnnouncementHost^ s_hostProducer;
static std::vector<INarratorAnnouncementHost^> s_hosts;
static INarratorAnnouncementHost ^ s_hostProducer;
static std::vector<INarratorAnnouncementHost ^> s_hosts;
};
}

View File

@@ -13,17 +13,16 @@ using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Automation;
using namespace Windows::UI::Xaml::Automation::Peers;
DependencyProperty^ NarratorNotifier::s_announcementProperty;
DependencyProperty ^ NarratorNotifier::s_announcementProperty;
NarratorNotifier::NarratorNotifier()
{
m_announcementHost = NarratorAnnouncementHostFactory::MakeHost();
}
void NarratorNotifier::Announce(NarratorAnnouncement^ announcement)
void NarratorNotifier::Announce(NarratorAnnouncement ^ announcement)
{
if (NarratorAnnouncement::IsValid(announcement)
&& m_announcementHost != nullptr)
if (NarratorAnnouncement::IsValid(announcement) && m_announcementHost != nullptr)
{
m_announcementHost->Announce(announcement);
}
@@ -31,20 +30,18 @@ void NarratorNotifier::Announce(NarratorAnnouncement^ announcement)
void NarratorNotifier::RegisterDependencyProperties()
{
s_announcementProperty = DependencyProperty::Register(
L"Announcement", // The name of the dependency property.
NarratorAnnouncement::typeid, // The type of the dependency property.
NarratorNotifier::typeid, // The owner of the dependency property.
ref new PropertyMetadata(
nullptr, // Default value of the dependency property.
ref new PropertyChangedCallback(OnAnnouncementChanged)));
s_announcementProperty = DependencyProperty::Register(L"Announcement", // The name of the dependency property.
NarratorAnnouncement::typeid, // The type of the dependency property.
NarratorNotifier::typeid, // The owner of the dependency property.
ref new PropertyMetadata(nullptr, // Default value of the dependency property.
ref new PropertyChangedCallback(OnAnnouncementChanged)));
}
void NarratorNotifier::OnAnnouncementChanged(_In_ DependencyObject^ dependencyObject, _In_ DependencyPropertyChangedEventArgs^ e)
void NarratorNotifier::OnAnnouncementChanged(_In_ DependencyObject ^ dependencyObject, _In_ DependencyPropertyChangedEventArgs ^ e)
{
auto instance = safe_cast<NarratorNotifier^>(dependencyObject);
auto instance = safe_cast<NarratorNotifier ^>(dependencyObject);
if (instance != nullptr)
{
instance->Announce(safe_cast<NarratorAnnouncement^>(e->NewValue));
instance->Announce(safe_cast<NarratorAnnouncement ^>(e->NewValue));
}
}

View File

@@ -8,12 +8,13 @@
namespace CalculatorApp::Common::Automation
{
public ref class NarratorNotifier sealed : public Windows::UI::Xaml::DependencyObject
public
ref class NarratorNotifier sealed : public Windows::UI::Xaml::DependencyObject
{
public:
NarratorNotifier();
void Announce(NarratorAnnouncement^ announcement);
void Announce(NarratorAnnouncement ^ announcement);
property NarratorAnnouncement^ Announcement
{
@@ -26,32 +27,25 @@ namespace CalculatorApp::Common::Automation
static void RegisterDependencyProperties();
static property Windows::UI::Xaml::DependencyProperty^ AnnouncementProperty
{
Windows::UI::Xaml::DependencyProperty^ get()
{
return s_announcementProperty;
}
}
static property Windows::UI::Xaml::DependencyProperty
^ AnnouncementProperty { Windows::UI::Xaml::DependencyProperty ^ get() { return s_announcementProperty; } }
static NarratorAnnouncement^ GetAnnouncement(Windows::UI::Xaml::DependencyObject^ element)
{
return safe_cast<NarratorAnnouncement^>(element->GetValue(s_announcementProperty));
}
static NarratorAnnouncement
^ GetAnnouncement(Windows::UI::Xaml::DependencyObject
^ element) { return safe_cast<NarratorAnnouncement ^>(element->GetValue(s_announcementProperty)); }
static void SetAnnouncement(Windows::UI::Xaml::DependencyObject^ element, NarratorAnnouncement^ value)
static void SetAnnouncement(Windows::UI::Xaml::DependencyObject ^ element, NarratorAnnouncement ^ value)
{
element->SetValue(s_announcementProperty, value);
}
private:
static void OnAnnouncementChanged(
_In_ Windows::UI::Xaml::DependencyObject^ dependencyObject,
_In_ Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ eventArgs);
static void OnAnnouncementChanged(_In_ Windows::UI::Xaml::DependencyObject ^ dependencyObject,
_In_ Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ eventArgs);
static Windows::UI::Xaml::DependencyProperty^ s_announcementProperty;
static Windows::UI::Xaml::DependencyProperty ^ s_announcementProperty;
private:
INarratorAnnouncementHost^ m_announcementHost;
INarratorAnnouncementHost ^ m_announcementHost;
};
}

View File

@@ -10,23 +10,21 @@ using namespace Windows::UI::Xaml::Automation;
using namespace Windows::UI::Xaml::Automation::Peers;
using namespace Windows::UI::Xaml::Controls;
NotificationHost::NotificationHost() :
m_host(nullptr)
{}
NotificationHost::NotificationHost() : m_host(nullptr)
{
}
bool NotificationHost::IsHostAvailable()
{
return ApiInformation::IsMethodPresent(
L"Windows.UI.Xaml.Automation.Peers.AutomationPeer",
L"RaiseNotificationEvent");
return ApiInformation::IsMethodPresent(L"Windows.UI.Xaml.Automation.Peers.AutomationPeer", L"RaiseNotificationEvent");
}
INarratorAnnouncementHost^ NotificationHost::MakeHost()
INarratorAnnouncementHost ^ NotificationHost::MakeHost()
{
return ref new NotificationHost();
}
void NotificationHost::Announce(NarratorAnnouncement^ announcement)
void NotificationHost::Announce(NarratorAnnouncement ^ announcement)
{
if (m_host == nullptr)
{
@@ -36,16 +34,12 @@ void NotificationHost::Announce(NarratorAnnouncement^ announcement)
auto peer = FrameworkElementAutomationPeer::FromElement(m_host);
if (peer != nullptr)
{
peer->RaiseNotificationEvent(
GetWindowsNotificationKind(announcement->Kind),
GetWindowsNotificationProcessing(announcement->Processing),
announcement->Announcement,
announcement->ActivityId);
peer->RaiseNotificationEvent(GetWindowsNotificationKind(announcement->Kind), GetWindowsNotificationProcessing(announcement->Processing),
announcement->Announcement, announcement->ActivityId);
}
}
StandardPeers::AutomationNotificationKind NotificationHost::GetWindowsNotificationKind(
CustomPeers::AutomationNotificationKind customKindType)
StandardPeers::AutomationNotificationKind NotificationHost::GetWindowsNotificationKind(CustomPeers::AutomationNotificationKind customKindType)
{
switch (customKindType)
{
@@ -71,8 +65,8 @@ StandardPeers::AutomationNotificationKind NotificationHost::GetWindowsNotificati
return StandardPeers::AutomationNotificationKind::Other;
}
StandardPeers::AutomationNotificationProcessing NotificationHost::GetWindowsNotificationProcessing(
CustomPeers::AutomationNotificationProcessing customProcessingType)
StandardPeers::AutomationNotificationProcessing
NotificationHost::GetWindowsNotificationProcessing(CustomPeers::AutomationNotificationProcessing customProcessingType)
{
switch (customProcessingType)
{

View File

@@ -10,25 +10,25 @@
namespace CalculatorApp::Common::Automation
{
public ref class NotificationHost sealed : public INarratorAnnouncementHost
public
ref class NotificationHost sealed : public INarratorAnnouncementHost
{
public:
NotificationHost();
virtual bool IsHostAvailable();
virtual INarratorAnnouncementHost^ MakeHost();
virtual INarratorAnnouncementHost ^ MakeHost();
virtual void Announce(NarratorAnnouncement^ announcement);
virtual void Announce(NarratorAnnouncement ^ announcement);
private:
static Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind GetWindowsNotificationKind(
CalculatorApp::Common::Automation::AutomationNotificationKind customKindType);
static Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind
GetWindowsNotificationKind(CalculatorApp::Common::Automation::AutomationNotificationKind customKindType);
static Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing GetWindowsNotificationProcessing(
CalculatorApp::Common::Automation::AutomationNotificationProcessing customProcessingType);
static Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing
GetWindowsNotificationProcessing(CalculatorApp::Common::Automation::AutomationNotificationProcessing customProcessingType);
private:
Windows::UI::Xaml::UIElement^ m_host;
Windows::UI::Xaml::UIElement ^ m_host;
};
}

View File

@@ -13,22 +13,22 @@ using namespace Windows::UI::Xaml::Data;
/// Notifies listeners that a property value has changed.
/// </summary>
/// <param name="propertyName">Name of the property used to notify listeners.</param>
void BindableBase::OnPropertyChanged(String^ propertyName)
void BindableBase::OnPropertyChanged(String ^ propertyName)
{
PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName));
}
Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetCustomProperty(Platform::String^ name)
Windows::UI::Xaml::Data::ICustomProperty ^ BindableBase::GetCustomProperty(Platform::String ^ name)
{
return nullptr;
}
Windows::UI::Xaml::Data::ICustomProperty^ BindableBase::GetIndexedProperty(Platform::String^ name, Windows::UI::Xaml::Interop::TypeName type)
Windows::UI::Xaml::Data::ICustomProperty ^ BindableBase::GetIndexedProperty(Platform::String ^ name, Windows::UI::Xaml::Interop::TypeName type)
{
return nullptr;
}
Platform::String^ BindableBase::GetStringRepresentation()
Platform::String ^ BindableBase::GetStringRepresentation()
{
return this->ToString();
}

View File

@@ -10,26 +10,29 @@ namespace CalculatorApp
/// <summary>
/// Implementation of <see cref="INotifyPropertyChanged"/> to simplify models.
/// </summary>
[Windows::Foundation::Metadata::WebHostHidden]
public ref class BindableBase : Windows::UI::Xaml::DependencyObject, Windows::UI::Xaml::Data::INotifyPropertyChanged, Windows::UI::Xaml::Data::ICustomPropertyProvider
[Windows::Foundation::Metadata::WebHostHidden] public ref class BindableBase : Windows::UI::Xaml::DependencyObject,
Windows::UI::Xaml::Data::INotifyPropertyChanged,
Windows::UI::Xaml::Data::ICustomPropertyProvider
{
public:
virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;
virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler ^ PropertyChanged;
public:
// ICustomPropertyProvider
virtual Windows::UI::Xaml::Data::ICustomProperty^ GetCustomProperty(Platform::String^ name);
virtual Windows::UI::Xaml::Data::ICustomProperty^ GetIndexedProperty(Platform::String^ name, Windows::UI::Xaml::Interop::TypeName type);
virtual Platform::String^ GetStringRepresentation();
virtual Windows::UI::Xaml::Data::ICustomProperty ^ GetCustomProperty(Platform::String ^ name);
virtual Windows::UI::Xaml::Data::ICustomProperty ^ GetIndexedProperty(Platform::String ^ name, Windows::UI::Xaml::Interop::TypeName type);
virtual Platform::String ^ GetStringRepresentation();
property Windows::UI::Xaml::Interop::TypeName Type
{
virtual Windows::UI::Xaml::Interop::TypeName get() { return this->GetType(); }
virtual Windows::UI::Xaml::Interop::TypeName get()
{
return this->GetType();
}
}
protected:
virtual void OnPropertyChanged(Platform::String^ propertyName);
virtual void OnPropertyChanged(Platform::String ^ propertyName);
};
}
}

View File

@@ -8,9 +8,9 @@ using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace Platform;
NumbersAndOperatorsEnum CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(_In_ Object^ commandParameter)
NumbersAndOperatorsEnum CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(_In_ Object ^ commandParameter)
{
auto eventArgs = dynamic_cast<CalculatorButtonPressedEventArgs^>(commandParameter);
auto eventArgs = dynamic_cast<CalculatorButtonPressedEventArgs ^>(commandParameter);
if (eventArgs != nullptr)
{
return eventArgs->Operation;
@@ -21,9 +21,9 @@ NumbersAndOperatorsEnum CalculatorButtonPressedEventArgs::GetOperationFromComman
}
}
String^ CalculatorButtonPressedEventArgs::GetAuditoryFeedbackFromCommandParameter(_In_ Object^ commandParameter)
String ^ CalculatorButtonPressedEventArgs::GetAuditoryFeedbackFromCommandParameter(_In_ Object ^ commandParameter)
{
auto eventArgs = dynamic_cast<CalculatorButtonPressedEventArgs^>(commandParameter);
auto eventArgs = dynamic_cast<CalculatorButtonPressedEventArgs ^>(commandParameter);
if (eventArgs != nullptr)
{
return eventArgs->AuditoryFeedback;
@@ -33,4 +33,3 @@ String^ CalculatorButtonPressedEventArgs::GetAuditoryFeedbackFromCommandParamete
return nullptr;
}
}

View File

@@ -10,18 +10,20 @@ namespace CalculatorApp
{
namespace Common
{
public ref class CalculatorButtonPressedEventArgs sealed
public
ref class CalculatorButtonPressedEventArgs sealed
{
public:
PROPERTY_R(Platform::String^, AuditoryFeedback);
PROPERTY_R(Platform::String ^, AuditoryFeedback);
PROPERTY_R(CalculatorApp::NumbersAndOperatorsEnum, Operation);
CalculatorButtonPressedEventArgs(
Platform::String^ feedback, CalculatorApp::NumbersAndOperatorsEnum operation) :
m_AuditoryFeedback(feedback), m_Operation(operation) {}
CalculatorButtonPressedEventArgs(Platform::String ^ feedback, CalculatorApp::NumbersAndOperatorsEnum operation)
: m_AuditoryFeedback(feedback), m_Operation(operation)
{
}
static CalculatorApp::NumbersAndOperatorsEnum GetOperationFromCommandParameter(_In_ Platform::Object^ commandParameter);
static Platform::String^ GetAuditoryFeedbackFromCommandParameter(_In_ Platform::Object^ commandParameter);
static CalculatorApp::NumbersAndOperatorsEnum GetOperationFromCommandParameter(_In_ Platform::Object ^ commandParameter);
static Platform::String ^ GetAuditoryFeedbackFromCommandParameter(_In_ Platform::Object ^ commandParameter);
};
}
}

View File

@@ -9,205 +9,207 @@ namespace CalculatorApp
{
namespace CM = CalculationManager;
public enum class NumbersAndOperatorsEnum
public
enum class NumbersAndOperatorsEnum
{
Zero = (int) CM::Command::Command0,
One = (int) CM::Command::Command1,
Two = (int) CM::Command::Command2,
Three = (int) CM::Command::Command3,
Four = (int) CM::Command::Command4,
Five = (int) CM::Command::Command5,
Six = (int) CM::Command::Command6,
Seven = (int) CM::Command::Command7,
Eight = (int) CM::Command::Command8,
Nine = (int) CM::Command::Command9,
Add = (int) CM::Command::CommandADD,
Subtract = (int) CM::Command::CommandSUB,
Multiply = (int) CM::Command::CommandMUL,
Divide = (int) CM::Command::CommandDIV,
Invert = (int) CM::Command::CommandREC,
Equals = (int) CM::Command::CommandEQU,
Decimal = (int) CM::Command::CommandPNT,
Sqrt = (int) CM::Command::CommandSQRT,
Percent = (int) CM::Command::CommandPERCENT,
Negate = (int) CM::Command::CommandSIGN,
Backspace = (int) CM::Command::CommandBACK,
ClearEntry = (int) CM::Command::CommandCENTR,
Clear = (int) CM::Command::CommandCLEAR,
Degree = (int) CM::Command::CommandDEG,
Radians = (int) CM::Command::CommandRAD,
Grads = (int) CM::Command::CommandGRAD,
Degrees = (int) CM::Command::CommandDegrees,
OpenParenthesis = (int) CM::Command::CommandOPENP,
CloseParenthesis = (int) CM::Command::CommandCLOSEP,
Pi = (int) CM::Command::CommandPI,
Sin = (int) CM::Command::CommandSIN,
Cos = (int) CM::Command::CommandCOS,
Tan = (int) CM::Command::CommandTAN,
Factorial = (int) CM::Command::CommandFAC,
XPower2 = (int) CM::Command::CommandSQR,
Mod = (int) CM::Command::CommandMOD,
FToE = (int) CM::Command::CommandFE,
LogBaseE = (int) CM::Command::CommandLN,
InvSin = (int) CM::Command::CommandASIN,
InvCos = (int) CM::Command::CommandACOS,
InvTan = (int) CM::Command::CommandATAN,
LogBase10 = (int) CM::Command::CommandLOG,
XPowerY = (int) CM::Command::CommandPWR,
YRootX = (int) CM::Command::CommandROOT,
TenPowerX = (int) CM::Command::CommandPOW10,
EPowerX = (int) CM::Command::CommandPOWE,
Exp = (int) CM::Command::CommandEXP,
IsScientificMode = (int) CM::Command::ModeScientific,
IsStandardMode = (int) CM::Command::ModeBasic,
None = (int) CM::Command::CommandNULL,
IsProgrammerMode = (int) CM::Command::ModeProgrammer,
DecButton = (int) CM::Command::CommandDec,
OctButton = (int) CM::Command::CommandOct,
HexButton = (int) CM::Command::CommandHex,
BinButton = (int) CM::Command::CommandBin,
And = (int) CM::Command::CommandAnd,
Ror = (int) CM::Command::CommandROR,
Rol = (int) CM::Command::CommandROL,
Or = (int) CM::Command::CommandOR,
Lsh = (int) CM::Command::CommandLSHF,
Rsh = (int) CM::Command::CommandRSHF,
Xor = (int) CM::Command::CommandXor,
Not = (int) CM::Command::CommandNot,
A = (int) CM::Command::CommandA,
B = (int) CM::Command::CommandB,
C = (int) CM::Command::CommandC,
D = (int) CM::Command::CommandD,
E = (int) CM::Command::CommandE,
F = (int) CM::Command::CommandF,
Zero = (int)CM::Command::Command0,
One = (int)CM::Command::Command1,
Two = (int)CM::Command::Command2,
Three = (int)CM::Command::Command3,
Four = (int)CM::Command::Command4,
Five = (int)CM::Command::Command5,
Six = (int)CM::Command::Command6,
Seven = (int)CM::Command::Command7,
Eight = (int)CM::Command::Command8,
Nine = (int)CM::Command::Command9,
Add = (int)CM::Command::CommandADD,
Subtract = (int)CM::Command::CommandSUB,
Multiply = (int)CM::Command::CommandMUL,
Divide = (int)CM::Command::CommandDIV,
Invert = (int)CM::Command::CommandREC,
Equals = (int)CM::Command::CommandEQU,
Decimal = (int)CM::Command::CommandPNT,
Sqrt = (int)CM::Command::CommandSQRT,
Percent = (int)CM::Command::CommandPERCENT,
Negate = (int)CM::Command::CommandSIGN,
Backspace = (int)CM::Command::CommandBACK,
ClearEntry = (int)CM::Command::CommandCENTR,
Clear = (int)CM::Command::CommandCLEAR,
Degree = (int)CM::Command::CommandDEG,
Radians = (int)CM::Command::CommandRAD,
Grads = (int)CM::Command::CommandGRAD,
Degrees = (int)CM::Command::CommandDegrees,
OpenParenthesis = (int)CM::Command::CommandOPENP,
CloseParenthesis = (int)CM::Command::CommandCLOSEP,
Pi = (int)CM::Command::CommandPI,
Sin = (int)CM::Command::CommandSIN,
Cos = (int)CM::Command::CommandCOS,
Tan = (int)CM::Command::CommandTAN,
Factorial = (int)CM::Command::CommandFAC,
XPower2 = (int)CM::Command::CommandSQR,
Mod = (int)CM::Command::CommandMOD,
FToE = (int)CM::Command::CommandFE,
LogBaseE = (int)CM::Command::CommandLN,
InvSin = (int)CM::Command::CommandASIN,
InvCos = (int)CM::Command::CommandACOS,
InvTan = (int)CM::Command::CommandATAN,
LogBase10 = (int)CM::Command::CommandLOG,
XPowerY = (int)CM::Command::CommandPWR,
YRootX = (int)CM::Command::CommandROOT,
TenPowerX = (int)CM::Command::CommandPOW10,
EPowerX = (int)CM::Command::CommandPOWE,
Exp = (int)CM::Command::CommandEXP,
IsScientificMode = (int)CM::Command::ModeScientific,
IsStandardMode = (int)CM::Command::ModeBasic,
None = (int)CM::Command::CommandNULL,
IsProgrammerMode = (int)CM::Command::ModeProgrammer,
DecButton = (int)CM::Command::CommandDec,
OctButton = (int)CM::Command::CommandOct,
HexButton = (int)CM::Command::CommandHex,
BinButton = (int)CM::Command::CommandBin,
And = (int)CM::Command::CommandAnd,
Ror = (int)CM::Command::CommandROR,
Rol = (int)CM::Command::CommandROL,
Or = (int)CM::Command::CommandOR,
Lsh = (int)CM::Command::CommandLSHF,
Rsh = (int)CM::Command::CommandRSHF,
Xor = (int)CM::Command::CommandXor,
Not = (int)CM::Command::CommandNot,
A = (int)CM::Command::CommandA,
B = (int)CM::Command::CommandB,
C = (int)CM::Command::CommandC,
D = (int)CM::Command::CommandD,
E = (int)CM::Command::CommandE,
F = (int)CM::Command::CommandF,
Memory, // This is the memory button. Doesn't have a direct mapping to the CalcEngine.
Sinh = (int) CM::Command::CommandSINH,
Cosh = (int) CM::Command::CommandCOSH,
Tanh = (int) CM::Command::CommandTANH,
InvSinh = (int) CM::Command::CommandASINH,
InvCosh = (int) CM::Command::CommandACOSH,
InvTanh = (int) CM::Command::CommandATANH,
Qword = (int) CM::Command::CommandQword,
Dword = (int) CM::Command::CommandDword,
Word = (int) CM::Command::CommandWord,
Byte = (int) CM::Command::CommandByte,
Cube = (int) CM::Command::CommandCUB,
DMS = (int) CM::Command::CommandDMS,
Sinh = (int)CM::Command::CommandSINH,
Cosh = (int)CM::Command::CommandCOSH,
Tanh = (int)CM::Command::CommandTANH,
InvSinh = (int)CM::Command::CommandASINH,
InvCosh = (int)CM::Command::CommandACOSH,
InvTanh = (int)CM::Command::CommandATANH,
Qword = (int)CM::Command::CommandQword,
Dword = (int)CM::Command::CommandDword,
Word = (int)CM::Command::CommandWord,
Byte = (int)CM::Command::CommandByte,
Cube = (int)CM::Command::CommandCUB,
DMS = (int)CM::Command::CommandDMS,
BINSTART = (int) CM::Command::CommandBINEDITSTART,
BINPOS0 = (int) CM::Command::CommandBINPOS0,
BINPOS1 = (int) CM::Command::CommandBINPOS1,
BINPOS2 = (int) CM::Command::CommandBINPOS2,
BINPOS3 = (int) CM::Command::CommandBINPOS3,
BINPOS4 = (int) CM::Command::CommandBINPOS4,
BINPOS5 = (int) CM::Command::CommandBINPOS5,
BINPOS6 = (int) CM::Command::CommandBINPOS6,
BINPOS7 = (int) CM::Command::CommandBINPOS7,
BINPOS8 = (int) CM::Command::CommandBINPOS8,
BINPOS9 = (int) CM::Command::CommandBINPOS9,
BINPOS10 = (int) CM::Command::CommandBINPOS10,
BINPOS11 = (int) CM::Command::CommandBINPOS11,
BINPOS12 = (int) CM::Command::CommandBINPOS12,
BINPOS13 = (int) CM::Command::CommandBINPOS13,
BINPOS14 = (int) CM::Command::CommandBINPOS14,
BINPOS15 = (int) CM::Command::CommandBINPOS15,
BINPOS16 = (int) CM::Command::CommandBINPOS16,
BINPOS17 = (int) CM::Command::CommandBINPOS17,
BINPOS18 = (int) CM::Command::CommandBINPOS18,
BINPOS19 = (int) CM::Command::CommandBINPOS19,
BINPOS20 = (int) CM::Command::CommandBINPOS20,
BINPOS21 = (int) CM::Command::CommandBINPOS21,
BINPOS22 = (int) CM::Command::CommandBINPOS22,
BINPOS23 = (int) CM::Command::CommandBINPOS23,
BINPOS24 = (int) CM::Command::CommandBINPOS24,
BINPOS25 = (int) CM::Command::CommandBINPOS25,
BINPOS26 = (int) CM::Command::CommandBINPOS26,
BINPOS27 = (int) CM::Command::CommandBINPOS27,
BINPOS28 = (int) CM::Command::CommandBINPOS28,
BINPOS29 = (int) CM::Command::CommandBINPOS29,
BINPOS30 = (int) CM::Command::CommandBINPOS30,
BINPOS31 = (int) CM::Command::CommandBINPOS31,
BINPOS32 = (int) CM::Command::CommandBINPOS32,
BINPOS33 = (int) CM::Command::CommandBINPOS33,
BINPOS34 = (int) CM::Command::CommandBINPOS34,
BINPOS35 = (int) CM::Command::CommandBINPOS35,
BINPOS36 = (int) CM::Command::CommandBINPOS36,
BINPOS37 = (int) CM::Command::CommandBINPOS37,
BINPOS38 = (int) CM::Command::CommandBINPOS38,
BINPOS39 = (int) CM::Command::CommandBINPOS39,
BINPOS40 = (int) CM::Command::CommandBINPOS40,
BINPOS41 = (int) CM::Command::CommandBINPOS41,
BINPOS42 = (int) CM::Command::CommandBINPOS42,
BINPOS43 = (int) CM::Command::CommandBINPOS43,
BINPOS44 = (int) CM::Command::CommandBINPOS44,
BINPOS45 = (int) CM::Command::CommandBINPOS45,
BINPOS46 = (int) CM::Command::CommandBINPOS46,
BINPOS47 = (int) CM::Command::CommandBINPOS47,
BINPOS48 = (int) CM::Command::CommandBINPOS48,
BINPOS49 = (int) CM::Command::CommandBINPOS49,
BINPOS50 = (int) CM::Command::CommandBINPOS50,
BINPOS51 = (int) CM::Command::CommandBINPOS51,
BINPOS52 = (int) CM::Command::CommandBINPOS52,
BINPOS53 = (int) CM::Command::CommandBINPOS53,
BINPOS54 = (int) CM::Command::CommandBINPOS54,
BINPOS55 = (int) CM::Command::CommandBINPOS55,
BINPOS56 = (int) CM::Command::CommandBINPOS56,
BINPOS57 = (int) CM::Command::CommandBINPOS57,
BINPOS58 = (int) CM::Command::CommandBINPOS58,
BINPOS59 = (int) CM::Command::CommandBINPOS59,
BINPOS60 = (int) CM::Command::CommandBINPOS60,
BINPOS61 = (int) CM::Command::CommandBINPOS61,
BINPOS62 = (int) CM::Command::CommandBINPOS62,
BINPOS63 = (int) CM::Command::CommandBINPOS63,
BINEND = (int) CM::Command::CommandBINEDITEND,
Hyp = (int) CM::Command::CommandHYP
BINSTART = (int)CM::Command::CommandBINEDITSTART,
BINPOS0 = (int)CM::Command::CommandBINPOS0,
BINPOS1 = (int)CM::Command::CommandBINPOS1,
BINPOS2 = (int)CM::Command::CommandBINPOS2,
BINPOS3 = (int)CM::Command::CommandBINPOS3,
BINPOS4 = (int)CM::Command::CommandBINPOS4,
BINPOS5 = (int)CM::Command::CommandBINPOS5,
BINPOS6 = (int)CM::Command::CommandBINPOS6,
BINPOS7 = (int)CM::Command::CommandBINPOS7,
BINPOS8 = (int)CM::Command::CommandBINPOS8,
BINPOS9 = (int)CM::Command::CommandBINPOS9,
BINPOS10 = (int)CM::Command::CommandBINPOS10,
BINPOS11 = (int)CM::Command::CommandBINPOS11,
BINPOS12 = (int)CM::Command::CommandBINPOS12,
BINPOS13 = (int)CM::Command::CommandBINPOS13,
BINPOS14 = (int)CM::Command::CommandBINPOS14,
BINPOS15 = (int)CM::Command::CommandBINPOS15,
BINPOS16 = (int)CM::Command::CommandBINPOS16,
BINPOS17 = (int)CM::Command::CommandBINPOS17,
BINPOS18 = (int)CM::Command::CommandBINPOS18,
BINPOS19 = (int)CM::Command::CommandBINPOS19,
BINPOS20 = (int)CM::Command::CommandBINPOS20,
BINPOS21 = (int)CM::Command::CommandBINPOS21,
BINPOS22 = (int)CM::Command::CommandBINPOS22,
BINPOS23 = (int)CM::Command::CommandBINPOS23,
BINPOS24 = (int)CM::Command::CommandBINPOS24,
BINPOS25 = (int)CM::Command::CommandBINPOS25,
BINPOS26 = (int)CM::Command::CommandBINPOS26,
BINPOS27 = (int)CM::Command::CommandBINPOS27,
BINPOS28 = (int)CM::Command::CommandBINPOS28,
BINPOS29 = (int)CM::Command::CommandBINPOS29,
BINPOS30 = (int)CM::Command::CommandBINPOS30,
BINPOS31 = (int)CM::Command::CommandBINPOS31,
BINPOS32 = (int)CM::Command::CommandBINPOS32,
BINPOS33 = (int)CM::Command::CommandBINPOS33,
BINPOS34 = (int)CM::Command::CommandBINPOS34,
BINPOS35 = (int)CM::Command::CommandBINPOS35,
BINPOS36 = (int)CM::Command::CommandBINPOS36,
BINPOS37 = (int)CM::Command::CommandBINPOS37,
BINPOS38 = (int)CM::Command::CommandBINPOS38,
BINPOS39 = (int)CM::Command::CommandBINPOS39,
BINPOS40 = (int)CM::Command::CommandBINPOS40,
BINPOS41 = (int)CM::Command::CommandBINPOS41,
BINPOS42 = (int)CM::Command::CommandBINPOS42,
BINPOS43 = (int)CM::Command::CommandBINPOS43,
BINPOS44 = (int)CM::Command::CommandBINPOS44,
BINPOS45 = (int)CM::Command::CommandBINPOS45,
BINPOS46 = (int)CM::Command::CommandBINPOS46,
BINPOS47 = (int)CM::Command::CommandBINPOS47,
BINPOS48 = (int)CM::Command::CommandBINPOS48,
BINPOS49 = (int)CM::Command::CommandBINPOS49,
BINPOS50 = (int)CM::Command::CommandBINPOS50,
BINPOS51 = (int)CM::Command::CommandBINPOS51,
BINPOS52 = (int)CM::Command::CommandBINPOS52,
BINPOS53 = (int)CM::Command::CommandBINPOS53,
BINPOS54 = (int)CM::Command::CommandBINPOS54,
BINPOS55 = (int)CM::Command::CommandBINPOS55,
BINPOS56 = (int)CM::Command::CommandBINPOS56,
BINPOS57 = (int)CM::Command::CommandBINPOS57,
BINPOS58 = (int)CM::Command::CommandBINPOS58,
BINPOS59 = (int)CM::Command::CommandBINPOS59,
BINPOS60 = (int)CM::Command::CommandBINPOS60,
BINPOS61 = (int)CM::Command::CommandBINPOS61,
BINPOS62 = (int)CM::Command::CommandBINPOS62,
BINPOS63 = (int)CM::Command::CommandBINPOS63,
BINEND = (int)CM::Command::CommandBINEDITEND,
Hyp = (int)CM::Command::CommandHYP
};
// This contains list of functions whose usage we are tracelogging
public enum class FunctionLogEnum
public
enum class FunctionLogEnum
{
Invert = (int) CM::Command::CommandREC,
Sqrt = (int) CM::Command::CommandSQRT,
Percent = (int) CM::Command::CommandPERCENT,
Negate = (int) CM::Command::CommandSIGN,
Degrees = (int) CM::Command::CommandDegrees,
Pi = (int) CM::Command::CommandPI,
Sin = (int) CM::Command::CommandSIN,
Cos = (int) CM::Command::CommandCOS,
Tan = (int) CM::Command::CommandTAN,
Factorial = (int) CM::Command::CommandFAC,
XPower2 = (int) CM::Command::CommandSQR,
Mod = (int) CM::Command::CommandMOD,
FToE = (int) CM::Command::CommandFE,
LogBaseE = (int) CM::Command::CommandLN,
InvSin = (int) CM::Command::CommandASIN,
InvCos = (int) CM::Command::CommandACOS,
InvTan = (int) CM::Command::CommandATAN,
LogBase10 = (int) CM::Command::CommandLOG,
XPowerY = (int) CM::Command::CommandPWR,
YRootX = (int) CM::Command::CommandROOT,
TenPowerX = (int) CM::Command::CommandPOW10,
EPowerX = (int) CM::Command::CommandPOWE,
Exp = (int) CM::Command::CommandEXP,
DecButton = (int) CM::Command::CommandDec,
OctButton = (int) CM::Command::CommandOct,
HexButton = (int) CM::Command::CommandHex,
BinButton = (int) CM::Command::CommandBin,
And = (int) CM::Command::CommandAnd,
Ror = (int) CM::Command::CommandROR,
Rol = (int) CM::Command::CommandROL,
Or = (int) CM::Command::CommandOR,
Lsh = (int) CM::Command::CommandLSHF,
Rsh = (int) CM::Command::CommandRSHF,
Xor = (int) CM::Command::CommandXor,
Not = (int) CM::Command::CommandNot,
Sinh = (int) CM::Command::CommandSINH,
Cosh = (int) CM::Command::CommandCOSH,
Tanh = (int) CM::Command::CommandTANH,
InvSinh = (int) CM::Command::CommandASINH,
InvCosh = (int) CM::Command::CommandACOSH,
InvTanh = (int) CM::Command::CommandATANH,
Cube = (int) CM::Command::CommandCUB,
DMS = (int) CM::Command::CommandDMS,
Invert = (int)CM::Command::CommandREC,
Sqrt = (int)CM::Command::CommandSQRT,
Percent = (int)CM::Command::CommandPERCENT,
Negate = (int)CM::Command::CommandSIGN,
Degrees = (int)CM::Command::CommandDegrees,
Pi = (int)CM::Command::CommandPI,
Sin = (int)CM::Command::CommandSIN,
Cos = (int)CM::Command::CommandCOS,
Tan = (int)CM::Command::CommandTAN,
Factorial = (int)CM::Command::CommandFAC,
XPower2 = (int)CM::Command::CommandSQR,
Mod = (int)CM::Command::CommandMOD,
FToE = (int)CM::Command::CommandFE,
LogBaseE = (int)CM::Command::CommandLN,
InvSin = (int)CM::Command::CommandASIN,
InvCos = (int)CM::Command::CommandACOS,
InvTan = (int)CM::Command::CommandATAN,
LogBase10 = (int)CM::Command::CommandLOG,
XPowerY = (int)CM::Command::CommandPWR,
YRootX = (int)CM::Command::CommandROOT,
TenPowerX = (int)CM::Command::CommandPOW10,
EPowerX = (int)CM::Command::CommandPOWE,
Exp = (int)CM::Command::CommandEXP,
DecButton = (int)CM::Command::CommandDec,
OctButton = (int)CM::Command::CommandOct,
HexButton = (int)CM::Command::CommandHex,
BinButton = (int)CM::Command::CommandBin,
And = (int)CM::Command::CommandAnd,
Ror = (int)CM::Command::CommandROR,
Rol = (int)CM::Command::CommandROL,
Or = (int)CM::Command::CommandOR,
Lsh = (int)CM::Command::CommandLSHF,
Rsh = (int)CM::Command::CommandRSHF,
Xor = (int)CM::Command::CommandXor,
Not = (int)CM::Command::CommandNot,
Sinh = (int)CM::Command::CommandSINH,
Cosh = (int)CM::Command::CommandCOSH,
Tanh = (int)CM::Command::CommandTANH,
InvSinh = (int)CM::Command::CommandASINH,
InvCosh = (int)CM::Command::CommandACOSH,
InvTanh = (int)CM::Command::CommandATANH,
Cube = (int)CM::Command::CommandCUB,
DMS = (int)CM::Command::CommandDMS,
};
}

View File

@@ -69,11 +69,12 @@ void CalculatorDisplay::SetIsInError(bool isError)
}
}
void CalculatorDisplay::SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector <std::shared_ptr<IExpressionCommand>>> const &commands)
void CalculatorDisplay::SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands)
{
if (m_callbackReference != nullptr)
{
if(auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
{
calcVM->SetExpressionDisplay(tokens, commands);
}

View File

@@ -8,7 +8,7 @@
namespace CalculatorApp
{
// Callback interface to be implemented by the CalculatorManager
class CalculatorDisplay: public ICalcDisplay
class CalculatorDisplay : public ICalcDisplay
{
public:
CalculatorDisplay();
@@ -18,7 +18,8 @@ namespace CalculatorApp
private:
void SetPrimaryDisplay(_In_ const std::wstring& displayString, _In_ bool isError) override;
void SetIsInError(bool isError) override;
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override;
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands) override;
void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
void SetParenthesisNumber(_In_ unsigned int parenthesisCount) override;

View File

@@ -8,19 +8,19 @@ using namespace CalculatorApp::Common;
using namespace concurrency;
using namespace std;
ConversionResultTaskHelper::ConversionResultTaskHelper(unsigned int delay, const function<void()> functionToRun) :
m_delay{ delay },
m_storedFunction{ functionToRun }
ConversionResultTaskHelper::ConversionResultTaskHelper(unsigned int delay, const function<void()> functionToRun)
: m_delay{ delay }, m_storedFunction{ functionToRun }
{
auto token = m_cts.get_token();
auto delayTask = CompleteAfter(delay);
delayTask.then([this, token]()
{
if (!token.is_canceled())
{
m_storedFunction();
}
}, task_continuation_context::use_current());
delayTask.then(
[this, token]() {
if (!token.is_canceled())
{
m_storedFunction();
}
},
task_continuation_context::use_current());
}
ConversionResultTaskHelper::~ConversionResultTaskHelper()

View File

@@ -15,10 +15,7 @@ using namespace Windows::Foundation;
using namespace Windows::System;
using namespace Windows::ApplicationModel::DataTransfer;
String^ CopyPasteManager::supportedFormats[] =
{
StandardDataFormats::Text
};
String ^ CopyPasteManager::supportedFormats[] = { StandardDataFormats::Text };
static constexpr wstring_view c_validCharacterSet{ L"0123456789()+-*/.abcdefABCDEF" };
@@ -40,43 +37,26 @@ static const wstring c_binProgrammerChars = L"[0-1]+((_|'|`)[0-1]+)*";
static const wstring c_uIntSuffixes = L"[uU]?[lL]{0,2}";
// RegEx Patterns used by various modes
static const array<wregex, 1> standardModePatterns =
{
wregex(c_wspc + c_signedDecFloat + c_wspc)
};
static const array<wregex, 2> scientificModePatterns =
{
wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + c_wspcRParens),
wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + L"[e]([+]|[-])+\\d+" + c_wspcRParens)
};
static const array<array<wregex, 5>, 4> programmerModePatterns =
{ {
// Hex numbers like 5F, 4A0C, 0xa9, 0xFFull, 47CDh
{
wregex(c_wspcLParens + L"(0[xX])?" + c_hexProgrammerChars + c_uIntSuffixes + c_wspcRParens),
wregex(c_wspcLParens + c_hexProgrammerChars + L"[hH]?" + c_wspcRParens)
},
// Decimal numbers like -145, 145, 0n145, 123ull etc
{
wregex(c_wspcLParens + L"[-+]?" + c_decProgrammerChars + L"[lL]{0,2}" +c_wspcRParens),
wregex(c_wspcLParens + L"(0[nN])?" + c_decProgrammerChars + c_uIntSuffixes + c_wspcRParens)
},
// Octal numbers like 06, 010, 0t77, 0o77, 077ull etc
{
wregex(c_wspcLParens + L"(0[otOT])?" + c_octProgrammerChars + c_uIntSuffixes + c_wspcRParens)
},
// Binary numbers like 011010110, 0010110, 10101001, 1001b, 0b1001, 0y1001, 0b1001ull
{
wregex(c_wspcLParens + L"(0[byBY])?" + c_binProgrammerChars + c_uIntSuffixes + c_wspcRParens),
wregex(c_wspcLParens + c_binProgrammerChars + L"[bB]?" + c_wspcRParens)
}
} };
static const array<wregex, 1> unitConverterPatterns =
{
wregex(c_wspc + L"[-+]?\\d*[.]?\\d*" + c_wspc)
static const array<wregex, 1> standardModePatterns = { wregex(c_wspc + c_signedDecFloat + c_wspc) };
static const array<wregex, 2> scientificModePatterns = { wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat + c_wspcRParens),
wregex(L"(" + c_wspc + L"[-+]?)|(" + c_wspcLParenSigned + L")" + c_signedDecFloat
+ L"[e]([+]|[-])+\\d+" + c_wspcRParens) };
static const array<array<wregex, 5>, 4> programmerModePatterns = {
{ // Hex numbers like 5F, 4A0C, 0xa9, 0xFFull, 47CDh
{ wregex(c_wspcLParens + L"(0[xX])?" + c_hexProgrammerChars + c_uIntSuffixes + c_wspcRParens),
wregex(c_wspcLParens + c_hexProgrammerChars + L"[hH]?" + c_wspcRParens) },
// Decimal numbers like -145, 145, 0n145, 123ull etc
{ wregex(c_wspcLParens + L"[-+]?" + c_decProgrammerChars + L"[lL]{0,2}" + c_wspcRParens),
wregex(c_wspcLParens + L"(0[nN])?" + c_decProgrammerChars + c_uIntSuffixes + c_wspcRParens) },
// Octal numbers like 06, 010, 0t77, 0o77, 077ull etc
{ wregex(c_wspcLParens + L"(0[otOT])?" + c_octProgrammerChars + c_uIntSuffixes + c_wspcRParens) },
// Binary numbers like 011010110, 0010110, 10101001, 1001b, 0b1001, 0y1001, 0b1001ull
{ wregex(c_wspcLParens + L"(0[byBY])?" + c_binProgrammerChars + c_uIntSuffixes + c_wspcRParens),
wregex(c_wspcLParens + c_binProgrammerChars + L"[bB]?" + c_wspcRParens) } }
};
static const array<wregex, 1> unitConverterPatterns = { wregex(c_wspc + L"[-+]?\\d*[.]?\\d*" + c_wspc) };
void CopyPasteManager::CopyToClipboard(String^ stringToCopy)
void CopyPasteManager::CopyToClipboard(String ^ stringToCopy)
{
// Copy the string to the clipboard
auto dataPackage = ref new DataPackage();
@@ -84,7 +64,7 @@ void CopyPasteManager::CopyToClipboard(String^ stringToCopy)
Clipboard::SetContent(dataPackage);
}
task<String^> CopyPasteManager::GetStringToPaste(ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, int bitLengthType)
task<String ^> CopyPasteManager::GetStringToPaste(ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, int bitLengthType)
{
// Retrieve the text in the clipboard
auto dataPackageView = Clipboard::GetContent();
@@ -95,11 +75,9 @@ task<String^> CopyPasteManager::GetStringToPaste(ViewMode mode, CategoryGroupTyp
//-- add support to allow pasting for expressions like 1.3e12(as of now we allow 1.3e+12)
return create_task((dataPackageView->GetTextAsync(::StandardDataFormats::Text)))
.then([mode, modeType, programmerNumberBase, bitLengthType](String^ pastedText)
{
return ValidatePasteExpression(pastedText, mode, modeType, programmerNumberBase, bitLengthType);
}
, task_continuation_context::use_arbitrary());
.then([mode, modeType, programmerNumberBase,
bitLengthType](String ^ pastedText) { return ValidatePasteExpression(pastedText, mode, modeType, programmerNumberBase, bitLengthType); },
task_continuation_context::use_arbitrary());
}
int CopyPasteManager::ClipboardTextFormat()
@@ -116,14 +94,14 @@ int CopyPasteManager::ClipboardTextFormat()
return -1;
}
String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode mode, int programmerNumberBase, int bitLengthType)
String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode mode, int programmerNumberBase, int bitLengthType)
{
return CopyPasteManager::ValidatePasteExpression(pastedText, mode, NavCategory::GetGroupType(mode), programmerNumberBase, bitLengthType);
}
// return "NoOp" if pastedText is invalid else return pastedText
String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, int bitLengthType)
String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, int bitLengthType)
{
if (pastedText->Length() > MaxPasteableLength)
{
@@ -135,7 +113,7 @@ String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode m
wstring pasteExpression = pastedText->Data();
// Get english translated expression
String^ englishString = LocalizationSettings::GetInstance().GetEnglishValueFromLocalizedDigits(pasteExpression);
String ^ englishString = LocalizationSettings::GetInstance().GetEnglishValueFromLocalizedDigits(pasteExpression);
// Removing the spaces, comma separator from the pasteExpression to allow pasting of expressions like 1 + 2+1,333
pasteExpression = RemoveUnwantedCharsFromWstring(englishString->Data());
@@ -223,7 +201,8 @@ vector<wstring> CopyPasteManager::ExtractOperands(const wstring& pasteExpression
if ((pasteExpression.at(i) == L'+') || (pasteExpression.at(i) == L'-'))
{
// don't break the expression into operands if the encountered character corresponds to sign command(+-)
if (isPreviousOpenParen || startOfExpression || isPreviousOperator || ((mode != ViewMode::Programmer) && !((i != 0) && (pasteExpression.at(i - 1) != L'e'))))
if (isPreviousOpenParen || startOfExpression || isPreviousOperator
|| ((mode != ViewMode::Programmer) && !((i != 0) && (pasteExpression.at(i - 1) != L'e'))))
{
isPreviousOperator = false;
continue;
@@ -267,7 +246,7 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
}
vector<wregex> patterns{};
if (mode == ViewMode::Standard)
{
patterns.assign(standardModePatterns.begin(), standardModePatterns.end());
@@ -339,7 +318,7 @@ pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mo
{
constexpr size_t defaultMaxOperandLength = 0;
constexpr uint64_t defaultMaxValue = 0;
if (mode == ViewMode::Standard)
{
return make_pair(MaxStandardOperandLength, defaultMaxValue);
@@ -452,26 +431,28 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
}
size_t CopyPasteManager::OperandLength(const wstring& operand, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase)
{
if (modeType == CategoryGroupType::Converter) {
{
if (modeType == CategoryGroupType::Converter)
{
return operand.length();
}
switch(mode) {
case ViewMode::Standard:
case ViewMode::Scientific:
return StandardScientificOperandLength(operand);
switch (mode)
{
case ViewMode::Standard:
case ViewMode::Scientific:
return StandardScientificOperandLength(operand);
case ViewMode::Programmer:
return ProgrammerOperandLength(operand, programmerNumberBase);
case ViewMode::Programmer:
return ProgrammerOperandLength(operand, programmerNumberBase);
default:
return 0;
default:
return 0;
}
}
size_t CopyPasteManager::StandardScientificOperandLength(const wstring& operand)
{
{
const bool hasDecimal = operand.find('.') != wstring::npos;
if (hasDecimal)
@@ -494,7 +475,6 @@ size_t CopyPasteManager::StandardScientificOperandLength(const wstring& operand)
size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int numberBase)
{
vector<wstring> prefixes{};
vector<wstring> suffixes{};
switch (numberBase)
@@ -515,7 +495,7 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
break;
default:
// No defined prefixes/suffixes
return 0;
return 0;
}
// UInt suffixes are common across all modes

View File

@@ -25,8 +25,9 @@ namespace CalculatorApp
class CopyPasteManager
{
public:
static void CopyToClipboard(Platform::String^ stringToCopy);
static concurrency::task<Platform::String^> GetStringToPaste(CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1, int bitLengthType = -1);
static void CopyToClipboard(Platform::String ^ stringToCopy);
static concurrency::task<Platform::String ^> GetStringToPaste(CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType,
int programmerNumberBase = -1, int bitLengthType = -1);
static bool HasStringToPaste()
{
return ClipboardTextFormat() >= 0;
@@ -36,25 +37,23 @@ namespace CalculatorApp
private:
static int ClipboardTextFormat();
static Platform::String^ ValidatePasteExpression(
Platform::String^ pastedText,
CalculatorApp::Common::ViewMode mode,
int programmerNumberBase,
int bitLengthType);
static Platform::String^ ValidatePasteExpression(
Platform::String^ pastedText,
CalculatorApp::Common::ViewMode mode,
CalculatorApp::Common::CategoryGroupType modeType,
int programmerNumberBase,
int bitLengthType);
static Platform::String
^ ValidatePasteExpression(Platform::String ^ pastedText, CalculatorApp::Common::ViewMode mode, int programmerNumberBase, int bitLengthType);
static Platform::String
^ ValidatePasteExpression(Platform::String ^ pastedText, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType,
int programmerNumberBase, int bitLengthType);
static std::vector<std::wstring> ExtractOperands(const std::wstring& pasteExpression, CalculatorApp::Common::ViewMode mode, int programmerNumberBase = -1, int bitLengthType = -1);
static bool ExpressionRegExMatch(std::vector<std::wstring> operands, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1, int bitLengthType = -1);
static std::vector<std::wstring> ExtractOperands(const std::wstring& pasteExpression, CalculatorApp::Common::ViewMode mode,
int programmerNumberBase = -1, int bitLengthType = -1);
static bool ExpressionRegExMatch(std::vector<std::wstring> operands, CalculatorApp::Common::ViewMode mode,
CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1, int bitLengthType = -1);
static std::pair<size_t, uint64_t> GetMaxOperandLengthAndValue(CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1, int bitLengthType = -1);
static std::pair<size_t, uint64_t> GetMaxOperandLengthAndValue(CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType,
int programmerNumberBase = -1, int bitLengthType = -1);
static std::wstring SanitizeOperand(const std::wstring& operand);
static bool TryOperandToULL(const std::wstring& operand, int numberBase, unsigned long long int& result);
static size_t OperandLength(const std::wstring& operand, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1);
static size_t OperandLength(const std::wstring& operand, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType,
int programmerNumberBase = -1);
static size_t StandardScientificOperandLength(const std::wstring& operand);
static size_t ProgrammerOperandLength(const std::wstring& operand, int numberBase);
static std::wstring RemoveUnwantedCharsFromWstring(const std::wstring& input);
@@ -67,7 +66,7 @@ namespace CalculatorApp
static constexpr size_t MaxExponentLength = 4;
static constexpr size_t MaxProgrammerBitLength = 64;
static Platform::String^ supportedFormats[];
static Platform::String ^ supportedFormats[];
friend class CalculatorUnitTests::CopyPasteManagerTest;
};

View File

@@ -9,7 +9,7 @@ using namespace Windows::Foundation;
using namespace Windows::Globalization;
using namespace CalculatorApp::Common::DateCalculation;
DateCalculationEngine::DateCalculationEngine(_In_ String^ calendarIdentifier)
DateCalculationEngine::DateCalculationEngine(_In_ String ^ calendarIdentifier)
{
m_calendar = ref new Calendar();
m_calendar->ChangeTimeZone("UTC");
@@ -18,7 +18,7 @@ DateCalculationEngine::DateCalculationEngine(_In_ String^ calendarIdentifier)
// Adding Duration to a Date
// Returns: True if function succeeds to calculate the date else returns False
bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime *endDate)
bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime* endDate)
{
auto currentCalendarSystem = m_calendar->GetCalendarSystem();
@@ -28,9 +28,10 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date
// The Japanese Era system can have multiple year partitions within the same year.
// For example, April 30, 2019 is denoted April 30, Heisei 31; May 1, 2019 is denoted as May 1, Reiwa 1.
// The Calendar treats Heisei 31 and Reiwa 1 as separate years, which results in some unexpected behaviors where subtracting a year from Reiwa 1 results in a date in Heisei 31.
// To provide the expected result across era boundaries, we first convert the Japanese era system to a Gregorian system, do date math, and then convert back to the Japanese era system.
// This works because the Japanese era system maintains the same year/month boundaries and durations as the Gregorian system and is only different in display value.
// The Calendar treats Heisei 31 and Reiwa 1 as separate years, which results in some unexpected behaviors where subtracting a year from Reiwa 1 results
// in a date in Heisei 31. To provide the expected result across era boundaries, we first convert the Japanese era system to a Gregorian system, do date
// math, and then convert back to the Japanese era system. This works because the Japanese era system maintains the same year/month boundaries and
// durations as the Gregorian system and is only different in display value.
if (currentCalendarSystem == CalendarIdentifiers::Japanese)
{
m_calendar->ChangeCalendarSystem(CalendarIdentifiers::Gregorian);
@@ -51,7 +52,7 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date
*endDate = m_calendar->GetDateTime();
}
catch (Platform::InvalidArgumentException^ ex)
catch (Platform::InvalidArgumentException ^ ex)
{
// ensure that we revert to the correct calendar system
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
@@ -67,7 +68,7 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date
// Subtracting Duration from a Date
// Returns: True if function succeeds to calculate the date else returns False
bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime *endDate)
bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime* endDate)
{
auto currentCalendarSystem = m_calendar->GetCalendarSystem();
@@ -79,9 +80,10 @@ bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const
// The Japanese Era system can have multiple year partitions within the same year.
// For example, April 30, 2019 is denoted April 30, Heisei 31; May 1, 2019 is denoted as May 1, Reiwa 1.
// The Calendar treats Heisei 31 and Reiwa 1 as separate years, which results in some unexpected behaviors where subtracting a year from Reiwa 1 results in a date in Heisei 31.
// To provide the expected result across era boundaries, we first convert the Japanese era system to a Gregorian system, do date math, and then convert back to the Japanese era system.
// This works because the Japanese era system maintains the same year/month boundaries and durations as the Gregorian system and is only different in display value.
// The Calendar treats Heisei 31 and Reiwa 1 as separate years, which results in some unexpected behaviors where subtracting a year from Reiwa 1 results
// in a date in Heisei 31. To provide the expected result across era boundaries, we first convert the Japanese era system to a Gregorian system, do date
// math, and then convert back to the Japanese era system. This works because the Japanese era system maintains the same year/month boundaries and
// durations as the Gregorian system and is only different in display value.
if (currentCalendarSystem == CalendarIdentifiers::Japanese)
{
m_calendar->ChangeCalendarSystem(CalendarIdentifiers::Gregorian);
@@ -101,7 +103,7 @@ bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const
}
*endDate = m_calendar->GetDateTime();
}
catch (Platform::InvalidArgumentException^ ex)
catch (Platform::InvalidArgumentException ^ ex)
{
// ensure that we revert to the correct calendar system
m_calendar->ChangeCalendarSystem(currentCalendarSystem);
@@ -117,7 +119,7 @@ bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const
}
// Calculate the difference between two dates
void DateCalculationEngine::GetDateDifference(_In_ DateTime date1, _In_ DateTime date2, _In_ DateUnit outputFormat, _Out_ DateDifference *difference)
void DateCalculationEngine::GetDateDifference(_In_ DateTime date1, _In_ DateTime date2, _In_ DateUnit outputFormat, _Out_ DateDifference* difference)
{
DateTime startDate;
DateTime endDate;
@@ -149,8 +151,7 @@ void DateCalculationEngine::GetDateDifference(_In_ DateTime date1, _In_ DateTime
UINT approximateDaysInYear;
// If we're unable to calculate the days-in-month or days-in-year, we'll leave the values at 0.
if (TryGetCalendarDaysInMonth(startDate, daysInMonth)
&& TryGetCalendarDaysInYear(endDate, approximateDaysInYear))
if (TryGetCalendarDaysInMonth(startDate, daysInMonth) && TryGetCalendarDaysInYear(endDate, approximateDaysInYear))
{
UINT daysIn[c_unitsOfDate] = { approximateDaysInYear, daysInMonth, c_daysInWeek, 1 };
@@ -172,7 +173,7 @@ void DateCalculationEngine::GetDateDifference(_In_ DateTime date1, _In_ DateTime
{
pivotDate = AdjustCalendarDate(pivotDate, dateUnit, static_cast<int>(differenceInDates[unitIndex]));
}
catch (Platform::InvalidArgumentException^)
catch (Platform::InvalidArgumentException ^)
{
// Operation failed due to out of bound result
// Do nothing
@@ -208,7 +209,7 @@ void DateCalculationEngine::GetDateDifference(_In_ DateTime date1, _In_ DateTime
pivotDate = AdjustCalendarDate(pivotDate, dateUnit, 1);
differenceInDates[unitIndex] += 1;
}
catch (Platform::InvalidArgumentException^)
catch (Platform::InvalidArgumentException ^)
{
// handling for 31st Dec, 9999 last valid date
// Do nothing - break out
@@ -233,7 +234,6 @@ void DateCalculationEngine::GetDateDifference(_In_ DateTime date1, _In_ DateTime
difference->day = differenceInDates[3];
}
// Private Methods
// Gets number of days between the two date time values
@@ -311,9 +311,10 @@ DateTime DateCalculationEngine::AdjustCalendarDate(Windows::Foundation::DateTime
// The Japanese Era system can have multiple year partitions within the same year.
// For example, April 30, 2019 is denoted April 30, Heisei 31; May 1, 2019 is denoted as May 1, Reiwa 1.
// The Calendar treats Heisei 31 and Reiwa 1 as separate years, which results in some unexpected behaviors where subtracting a year from Reiwa 1 results in a date in Heisei 31.
// To provide the expected result across era boundaries, we first convert the Japanese era system to a Gregorian system, do date math, and then convert back to the Japanese era system.
// This works because the Japanese era system maintains the same year/month boundaries and durations as the Gregorian system and is only different in display value.
// The Calendar treats Heisei 31 and Reiwa 1 as separate years, which results in some unexpected behaviors where subtracting a year from Reiwa 1 results in
// a date in Heisei 31. To provide the expected result across era boundaries, we first convert the Japanese era system to a Gregorian system, do date math,
// and then convert back to the Japanese era system. This works because the Japanese era system maintains the same year/month boundaries and durations as
// the Gregorian system and is only different in display value.
auto currentCalendarSystem = m_calendar->GetCalendarSystem();
if (currentCalendarSystem == CalendarIdentifiers::Japanese)
{
@@ -322,15 +323,15 @@ DateTime DateCalculationEngine::AdjustCalendarDate(Windows::Foundation::DateTime
switch (dateUnit)
{
case DateUnit::Year:
m_calendar->AddYears(difference);
break;
case DateUnit::Month:
m_calendar->AddMonths(difference);
break;
case DateUnit::Week:
m_calendar->AddWeeks(difference);
break;
case DateUnit::Year:
m_calendar->AddYears(difference);
break;
case DateUnit::Month:
m_calendar->AddMonths(difference);
break;
case DateUnit::Week:
m_calendar->AddWeeks(difference);
break;
}
m_calendar->ChangeCalendarSystem(currentCalendarSystem);

View File

@@ -9,8 +9,8 @@ const uint64_t c_minute = 60 * c_second;
const uint64_t c_hour = 60 * c_minute;
const uint64_t c_day = 24 * c_hour;
const int c_unitsOfDate = 4; // Units Year,Month,Week,Day
const int c_unitsGreaterThanDays = 3; // Units Greater than Days (Year/Month/Week) 3
const int c_unitsOfDate = 4; // Units Year,Month,Week,Day
const int c_unitsGreaterThanDays = 3; // Units Greater than Days (Year/Month/Week) 3
const int c_daysInWeek = 7;
namespace CalculatorApp
@@ -19,7 +19,8 @@ namespace CalculatorApp
{
namespace DateCalculation
{
public enum class _Enum_is_bitflag_ DateUnit
public
enum class _Enum_is_bitflag_ DateUnit
{
Year = 0x01,
Month = 0x02,
@@ -40,16 +41,19 @@ namespace CalculatorApp
{
public:
// Constructor
DateCalculationEngine(_In_ Platform::String^ calendarIdentifier);
DateCalculationEngine(_In_ Platform::String ^ calendarIdentifier);
// Public Methods
bool __nothrow AddDuration(_In_ Windows::Foundation::DateTime startDate, _In_ const DateDifference& duration, _Out_ Windows::Foundation::DateTime *endDate);
bool __nothrow SubtractDuration(_In_ Windows::Foundation::DateTime startDate, _In_ const DateDifference& duration, _Out_ Windows::Foundation::DateTime *endDate);
void __nothrow GetDateDifference(_In_ Windows::Foundation::DateTime date1, _In_ Windows::Foundation::DateTime date2, _In_ DateUnit outputFormat, _Out_ DateDifference *difference);
bool __nothrow AddDuration(_In_ Windows::Foundation::DateTime startDate, _In_ const DateDifference& duration,
_Out_ Windows::Foundation::DateTime* endDate);
bool __nothrow SubtractDuration(_In_ Windows::Foundation::DateTime startDate, _In_ const DateDifference& duration,
_Out_ Windows::Foundation::DateTime* endDate);
void __nothrow GetDateDifference(_In_ Windows::Foundation::DateTime date1, _In_ Windows::Foundation::DateTime date2, _In_ DateUnit outputFormat,
_Out_ DateDifference* difference);
private:
// Private Variables
Windows::Globalization::Calendar^ m_calendar;
Windows::Globalization::Calendar ^ m_calendar;
// Private Methods
int GetDifferenceInDays(Windows::Foundation::DateTime date1, Windows::Foundation::DateTime date2);

View File

@@ -8,33 +8,31 @@ namespace CalculatorApp
namespace Common
{
template <typename TTarget>
ref class DelegateCommand: public Windows::UI::Xaml::Input::ICommand
ref class DelegateCommand : public Windows::UI::Xaml::Input::ICommand
{
internal:
internal :
typedef void (TTarget::*CommandHandlerFunc)(Platform::Object^);
typedef void (TTarget::*CommandHandlerFunc)(Platform::Object ^);
DelegateCommand(TTarget^ target, CommandHandlerFunc func):
m_weakTarget(target),
m_function(func)
{ }
DelegateCommand(TTarget ^ target, CommandHandlerFunc func) : m_weakTarget(target), m_function(func)
{
}
private:
// Explicit, and private, implementation of ICommand, this way of programming makes it so
// the ICommand methods will only be available if the ICommand interface is requested via a dynamic_cast
// The ICommand interface is meant to be consumed by Xaml and not by the app, this is a defensive measure against
// code in the app calling Execute.
virtual void ExecuteImpl(Platform::Object^ parameter) sealed = Windows::UI::Xaml::Input::ICommand::Execute
virtual void ExecuteImpl(Platform::Object ^ parameter) sealed = Windows::UI::Xaml::Input::ICommand::Execute
{
TTarget^ target = m_weakTarget.Resolve<TTarget>();
TTarget ^ target = m_weakTarget.Resolve<TTarget>();
if (target)
{
(target->*m_function)(parameter);
}
}
virtual bool CanExecuteImpl(Platform::Object^ parameter) sealed = Windows::UI::Xaml::Input::ICommand::CanExecute
virtual bool CanExecuteImpl(Platform::Object ^ parameter) sealed = Windows::UI::Xaml::Input::ICommand::CanExecute
{
return true;
}
@@ -57,14 +55,12 @@ namespace CalculatorApp
CommandHandlerFunc m_function;
Platform::WeakReference m_weakTarget;
};
template <typename TTarget, typename TFuncPtr>
DelegateCommand<TTarget>^ MakeDelegate(TTarget^ target, TFuncPtr&& function)
{
return ref new DelegateCommand<TTarget>(target, std::forward<TFuncPtr>(function));
}
DelegateCommand<TTarget> ^ MakeDelegate(TTarget ^ target, TFuncPtr&& function) {
return ref new DelegateCommand<TTarget>(target, std::forward<TFuncPtr>(function));
}
}
}

View File

@@ -7,30 +7,35 @@
namespace CalculatorApp::Common
{
public enum class TokenType
public
enum class TokenType
{
Operator,
Operand,
Separator
};
[Windows::UI::Xaml::Data::Bindable]
public ref class DisplayExpressionToken sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
[Windows::UI::Xaml::Data::Bindable] public ref class DisplayExpressionToken sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
internal:
DisplayExpressionToken(Platform::String^ token, int tokenPosition, bool fEditable, TokenType type) :
m_Token(token), m_TokenPosition(tokenPosition), m_IsTokenEditable(fEditable), m_Type(type), m_OriginalToken(token), m_InEditMode(false)
{}
internal : DisplayExpressionToken(Platform::String ^ token, int tokenPosition, bool fEditable, TokenType type)
: m_Token(token), m_TokenPosition(tokenPosition), m_IsTokenEditable(fEditable), m_Type(type), m_OriginalToken(token), m_InEditMode(false)
{
}
public:
OBSERVABLE_OBJECT();
OBSERVABLE_PROPERTY_RW(Platform::String^, Token);
OBSERVABLE_PROPERTY_RW(Platform::String ^, Token);
OBSERVABLE_PROPERTY_RW(int, TokenPosition);
OBSERVABLE_PROPERTY_RW(bool, IsTokenEditable);
OBSERVABLE_PROPERTY_RW(int, CommandIndex);
OBSERVABLE_PROPERTY_R(Platform::String^, OriginalToken);
OBSERVABLE_PROPERTY_R(Platform::String ^, OriginalToken);
property bool IsTokenInEditMode {
bool get() { return m_InEditMode; }
property bool IsTokenInEditMode
{
bool get()
{
return m_InEditMode;
}
void set(bool val)
{
if (!val)
@@ -40,8 +45,8 @@ namespace CalculatorApp::Common
m_InEditMode = val;
}
}
internal:
OBSERVABLE_PROPERTY_RW(TokenType, Type);
internal : OBSERVABLE_PROPERTY_RW(TokenType, Type);
private:
bool m_InEditMode;
};

View File

@@ -44,7 +44,7 @@ namespace CalculatorApp
}
StringReference idRef(id.c_str());
String^ str = m_resLoader->GetString(idRef);
String ^ str = m_resLoader->GetString(idRef);
return str->Begin();
}
}

View File

@@ -14,6 +14,6 @@ namespace CalculatorApp
virtual std::wstring GetCEngineString(const std::wstring& id) override;
private:
Windows::ApplicationModel::Resources::ResourceLoader^ m_resLoader;
Windows::ApplicationModel::Resources::ResourceLoader ^ m_resLoader;
};
}

View File

@@ -7,7 +7,9 @@
using namespace CalculatorApp::Common;
using namespace Windows::Storage::Streams;
CommandDeserializer::CommandDeserializer(_In_ DataReader^ dataReader) :m_dataReader(dataReader){}
CommandDeserializer::CommandDeserializer(_In_ DataReader ^ dataReader) : m_dataReader(dataReader)
{
}
std::shared_ptr<IExpressionCommand> CommandDeserializer::Deserialize(_In_ CalculationManager::CommandType cmdType)
{
@@ -20,7 +22,7 @@ std::shared_ptr<IExpressionCommand> CommandDeserializer::Deserialize(_In_ Calcul
case CalculationManager::CommandType::Parentheses:
return std::make_shared<CParentheses>(DeserializeParentheses());
return std::make_shared<CParentheses>(DeserializeParentheses());
break;
case CalculationManager::CommandType::UnaryCommand:

View File

@@ -12,11 +12,11 @@ namespace CalculatorApp
class CommandDeserializer
{
public:
CommandDeserializer(_In_ Windows::Storage::Streams::DataReader^ dataReader);
CommandDeserializer(_In_ Windows::Storage::Streams::DataReader ^ dataReader);
std::shared_ptr<IExpressionCommand> Deserialize(_In_ CalculationManager::CommandType cmdType);
private:
Windows::Storage::Streams::DataReader^ m_dataReader;
Windows::Storage::Streams::DataReader ^ m_dataReader;
COpndCommand DeserializeOperand();
CParentheses DeserializeParentheses();
CUnaryCommand DeserializeUnary();

View File

@@ -7,11 +7,11 @@
using namespace CalculatorApp::Common;
using namespace Windows::Storage::Streams;
SerializeCommandVisitor::SerializeCommandVisitor(_In_ DataWriter^ dataWriter) :m_dataWriter(dataWriter)
SerializeCommandVisitor::SerializeCommandVisitor(_In_ DataWriter ^ dataWriter) : m_dataWriter(dataWriter)
{
}
void SerializeCommandVisitor::Visit(_In_ COpndCommand &opndCmd)
void SerializeCommandVisitor::Visit(_In_ COpndCommand& opndCmd)
{
m_dataWriter->WriteBoolean(opndCmd.IsNegative());
m_dataWriter->WriteBoolean(opndCmd.IsDecimalPresent());
@@ -29,7 +29,7 @@ void SerializeCommandVisitor::Visit(_In_ COpndCommand &opndCmd)
}
}
void SerializeCommandVisitor::Visit(_In_ CUnaryCommand &unaryCmd)
void SerializeCommandVisitor::Visit(_In_ CUnaryCommand& unaryCmd)
{
auto cmds = unaryCmd.GetCommands();
unsigned int cmdSize;
@@ -43,13 +43,13 @@ void SerializeCommandVisitor::Visit(_In_ CUnaryCommand &unaryCmd)
}
}
void SerializeCommandVisitor::Visit(_In_ CBinaryCommand &binaryCmd)
void SerializeCommandVisitor::Visit(_In_ CBinaryCommand& binaryCmd)
{
int cmd = binaryCmd.GetCommand();
m_dataWriter->WriteInt32(cmd);
}
void SerializeCommandVisitor::Visit(_In_ CParentheses &paraCmd)
void SerializeCommandVisitor::Visit(_In_ CParentheses& paraCmd)
{
int parenthesisCmd = paraCmd.GetCommand();
m_dataWriter->WriteInt32(parenthesisCmd);

View File

@@ -12,15 +12,15 @@ namespace CalculatorApp
class SerializeCommandVisitor : public ISerializeCommandVisitor
{
public:
SerializeCommandVisitor(_In_ Windows::Storage::Streams::DataWriter^ dataWriter);
SerializeCommandVisitor(_In_ Windows::Storage::Streams::DataWriter ^ dataWriter);
void Visit(_In_ COpndCommand &opndCmd);
void Visit(_In_ CUnaryCommand &unaryCmd);
void Visit(_In_ CBinaryCommand &binaryCmd);
void Visit(_In_ CParentheses &paraCmd);
void Visit(_In_ COpndCommand& opndCmd);
void Visit(_In_ CUnaryCommand& unaryCmd);
void Visit(_In_ CBinaryCommand& binaryCmd);
void Visit(_In_ CParentheses& paraCmd);
private:
Windows::Storage::Streams::DataWriter^ m_dataWriter;
Windows::Storage::Streams::DataWriter ^ m_dataWriter;
};
}
}

View File

@@ -70,11 +70,11 @@ namespace CalculatorApp
}
}
void LightUpButton(ButtonBase^ button)
void LightUpButton(ButtonBase ^ button)
{
// If the button is a toggle button then we don't need
// to change the UI of the button
if (dynamic_cast<ToggleButton^>(button))
if (dynamic_cast<ToggleButton ^>(button))
{
return;
}
@@ -83,7 +83,7 @@ namespace CalculatorApp
VisualStateManager::GoToState(button, "Pressed", true);
// This timer will fire after lightUpTime and make the button
// go back to the normal state.
// go back to the normal state.
// This timer will only fire once after which it will be destroyed
auto timer = ref new DispatcherTimer();
TimeSpan lightUpTime{};
@@ -92,22 +92,20 @@ namespace CalculatorApp
WeakReference timerWeakReference(timer);
WeakReference buttonWeakReference(button);
timer->Tick += ref new EventHandler<Object^>(
[buttonWeakReference, timerWeakReference](Object^, Object^)
timer->Tick += ref new EventHandler<Object ^>([buttonWeakReference, timerWeakReference](Object ^, Object ^) {
auto button = buttonWeakReference.Resolve<ButtonBase>();
if (button)
{
auto button = buttonWeakReference.Resolve<ButtonBase>();
if (button)
{
VisualStateManager::GoToState(button, "Normal", true);
}
VisualStateManager::GoToState(button, "Normal", true);
}
// Cancel the timer after we're done so it only fires once
auto timer = timerWeakReference.Resolve<DispatcherTimer>();
if (timer)
{
timer->Stop();
}
});
// Cancel the timer after we're done so it only fires once
auto timer = timerWeakReference.Resolve<DispatcherTimer>();
if (timer)
{
timer->Stop();
}
});
timer->Start();
}
@@ -130,7 +128,7 @@ namespace CalculatorApp
}
}
void RunButtonCommand(ButtonBase^ button)
void RunButtonCommand(ButtonBase ^ button)
{
if (button->IsEnabled)
{
@@ -141,14 +139,14 @@ namespace CalculatorApp
command->Execute(parameter);
}
auto radio = dynamic_cast<RadioButton^>(button);
auto radio = dynamic_cast<RadioButton ^>(button);
if (radio)
{
radio->IsChecked = true;
return;
}
auto toggle = dynamic_cast<ToggleButton^>(button);
auto toggle = dynamic_cast<ToggleButton ^>(button);
if (toggle)
{
toggle->IsChecked = !toggle->IsChecked->Value;
@@ -163,7 +161,7 @@ static multimap<int, bool> s_ignoreNextEscape;
static multimap<int, bool> s_keepIgnoringEscape;
static multimap<int, bool> s_fHonorShortcuts;
static multimap<int, bool> s_fHandledEnter;
static multimap<int, Flyout^> s_AboutFlyout;
static multimap<int, Flyout ^> s_AboutFlyout;
void KeyboardShortcutManager::IgnoreEscape(bool onlyOnce)
{
@@ -205,15 +203,12 @@ void KeyboardShortcutManager::HonorEscape()
}
}
void KeyboardShortcutManager::OnCharacterPropertyChanged(
DependencyObject^ target,
String^ oldValue,
String^ newValue)
void KeyboardShortcutManager::OnCharacterPropertyChanged(DependencyObject ^ target, String ^ oldValue, String ^ newValue)
{
// Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto button = safe_cast<ButtonBase^>(target);
auto button = safe_cast<ButtonBase ^>(target);
int viewId = Utils::GetWindowId();
auto iterViewMap = s_CharacterForButtons.find(viewId);
@@ -254,15 +249,12 @@ void KeyboardShortcutManager::OnCharacterPropertyChanged(
}
}
void KeyboardShortcutManager::OnVirtualKeyPropertyChanged(
DependencyObject^ target,
MyVirtualKey /*oldValue*/,
MyVirtualKey newValue)
void KeyboardShortcutManager::OnVirtualKeyPropertyChanged(DependencyObject ^ target, MyVirtualKey /*oldValue*/, MyVirtualKey newValue)
{
// Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto button = static_cast<ButtonBase^>(target);
auto button = static_cast<ButtonBase ^>(target);
int viewId = Utils::GetWindowId();
auto iterViewMap = s_VirtualKeysForButtons.find(viewId);
@@ -280,20 +272,17 @@ void KeyboardShortcutManager::OnVirtualKeyPropertyChanged(
}
}
void KeyboardShortcutManager::OnVirtualKeyControlChordPropertyChanged(
DependencyObject^ target,
MyVirtualKey /*oldValue*/,
MyVirtualKey newValue)
void KeyboardShortcutManager::OnVirtualKeyControlChordPropertyChanged(DependencyObject ^ target, MyVirtualKey /*oldValue*/, MyVirtualKey newValue)
{
// Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
Control^ control = dynamic_cast<ButtonBase^>(target);
Control ^ control = dynamic_cast<ButtonBase ^>(target);
if (control == nullptr)
{
// Handling Ctrl+E shortcut for Date Calc, target would be NavigationView^ in that case
control = safe_cast<MUXC::NavigationView^>(target);
control = safe_cast<MUXC::NavigationView ^>(target);
}
int viewId = Utils::GetWindowId();
@@ -312,15 +301,12 @@ void KeyboardShortcutManager::OnVirtualKeyControlChordPropertyChanged(
}
}
void KeyboardShortcutManager::OnVirtualKeyShiftChordPropertyChanged(
DependencyObject^ target,
MyVirtualKey /*oldValue*/,
MyVirtualKey newValue)
void KeyboardShortcutManager::OnVirtualKeyShiftChordPropertyChanged(DependencyObject ^ target, MyVirtualKey /*oldValue*/, MyVirtualKey newValue)
{
// Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto button = safe_cast<ButtonBase^>(target);
auto button = safe_cast<ButtonBase ^>(target);
int viewId = Utils::GetWindowId();
auto iterViewMap = s_VirtualKeyShiftChordsForButtons.find(viewId);
@@ -338,15 +324,12 @@ void KeyboardShortcutManager::OnVirtualKeyShiftChordPropertyChanged(
}
}
void KeyboardShortcutManager::OnVirtualKeyAltChordPropertyChanged(
DependencyObject^ target,
MyVirtualKey /*oldValue*/,
MyVirtualKey newValue)
void KeyboardShortcutManager::OnVirtualKeyAltChordPropertyChanged(DependencyObject ^ target, MyVirtualKey /*oldValue*/, MyVirtualKey newValue)
{
// Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
MUXC::NavigationView^ navView = safe_cast<MUXC::NavigationView^>(target);
MUXC::NavigationView ^ navView = safe_cast<MUXC::NavigationView ^>(target);
int viewId = Utils::GetWindowId();
auto iterViewMap = s_VirtualKeyAltChordsForButtons.find(viewId);
@@ -364,15 +347,12 @@ void KeyboardShortcutManager::OnVirtualKeyAltChordPropertyChanged(
}
}
void KeyboardShortcutManager::OnVirtualKeyControlShiftChordPropertyChanged(
DependencyObject^ target,
MyVirtualKey /*oldValue*/,
MyVirtualKey newValue)
void KeyboardShortcutManager::OnVirtualKeyControlShiftChordPropertyChanged(DependencyObject ^ target, MyVirtualKey /*oldValue*/, MyVirtualKey newValue)
{
// Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto button = safe_cast<ButtonBase^>(target);
auto button = safe_cast<ButtonBase ^>(target);
int viewId = Utils::GetWindowId();
auto iterViewMap = s_VirtualKeyControlShiftChordsForButtons.find(viewId);
@@ -390,15 +370,12 @@ void KeyboardShortcutManager::OnVirtualKeyControlShiftChordPropertyChanged(
}
}
void KeyboardShortcutManager::OnVirtualKeyInverseChordPropertyChanged(
DependencyObject^ target,
MyVirtualKey /*oldValue*/,
MyVirtualKey newValue)
void KeyboardShortcutManager::OnVirtualKeyInverseChordPropertyChanged(DependencyObject ^ target, MyVirtualKey /*oldValue*/, MyVirtualKey newValue)
{
// Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto button = safe_cast<ButtonBase^>(target);
auto button = safe_cast<ButtonBase ^>(target);
int viewId = Utils::GetWindowId();
auto iterViewMap = s_VirtualKeyInverseChordsForButtons.find(viewId);
@@ -416,15 +393,12 @@ void KeyboardShortcutManager::OnVirtualKeyInverseChordPropertyChanged(
}
}
void KeyboardShortcutManager::OnVirtualKeyControlInverseChordPropertyChanged(
DependencyObject^ target,
MyVirtualKey /*oldValue*/,
MyVirtualKey newValue)
void KeyboardShortcutManager::OnVirtualKeyControlInverseChordPropertyChanged(DependencyObject ^ target, MyVirtualKey /*oldValue*/, MyVirtualKey newValue)
{
// Writer lock for the static maps
reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock);
auto button = safe_cast<ButtonBase^>(target);
auto button = safe_cast<ButtonBase ^>(target);
int viewId = Utils::GetWindowId();
auto iterViewMap = s_VirtualKeyControlInverseChordsForButtons.find(viewId);
@@ -445,7 +419,7 @@ void KeyboardShortcutManager::OnVirtualKeyControlInverseChordPropertyChanged(
// In the three event handlers below we will not mark the event as handled
// because this is a supplemental operation and we don't want to interfere with
// the normal keyboard handling.
void KeyboardShortcutManager::OnCharacterReceivedHandler(CoreWindow^ sender, CharacterReceivedEventArgs^ args)
void KeyboardShortcutManager::OnCharacterReceivedHandler(CoreWindow ^ sender, CharacterReceivedEventArgs ^ args)
{
int viewId = Utils::GetWindowId();
auto currentHonorShortcuts = s_fHonorShortcuts.find(viewId);
@@ -472,7 +446,8 @@ const std::multimap<MyVirtualKey, WeakReference>& GetCurrentKeyDictionary(MyVirt
{
return s_VirtualKeyAltChordsForButtons.find(viewId)->second;
}
else if ((s_ShiftKeyPressed.find(viewId)->second) && ((Window::Current->CoreWindow->GetKeyState(VirtualKey::Control) & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down))
else if ((s_ShiftKeyPressed.find(viewId)->second)
&& ((Window::Current->CoreWindow->GetKeyState(VirtualKey::Control) & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down))
{
return s_VirtualKeyControlShiftChordsForButtons.find(viewId)->second;
}
@@ -521,7 +496,7 @@ const std::multimap<MyVirtualKey, WeakReference>& GetCurrentKeyDictionary(MyVirt
}
}
void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow^ sender, KeyEventArgs^ args)
void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow ^ sender, KeyEventArgs ^ args)
{
// If keyboard shortcuts like Ctrl+C or Ctrl+V are not handled
if (!args->Handled)
@@ -536,25 +511,23 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow^ sender, KeyEventArgs^
bool isShiftKeyPressed = (currentShiftKeyPressed != s_ShiftKeyPressed.end()) && (currentShiftKeyPressed->second);
// Handle Ctrl + E for DateCalculator
if ((key == VirtualKey::E) &&
isControlKeyPressed &&
!isShiftKeyPressed)
if ((key == VirtualKey::E) && isControlKeyPressed && !isShiftKeyPressed)
{
const auto& lookupMap = GetCurrentKeyDictionary(static_cast<MyVirtualKey>(key));
auto buttons = lookupMap.equal_range(static_cast<MyVirtualKey>(key));
auto navView = buttons.first->second.Resolve<MUXC::NavigationView>();
auto appViewModel = safe_cast<ApplicationViewModel^>(navView->DataContext);
auto appViewModel = safe_cast<ApplicationViewModel ^>(navView->DataContext);
appViewModel->Mode = ViewMode::Date;
auto categoryName = AppResourceProvider::GetInstance().GetResourceString(L"DateCalculationModeText");
appViewModel->CategoryName = categoryName;
auto menuItems = static_cast<IObservableVector<Object^>^>(navView->MenuItemsSource);
auto menuItems = static_cast<IObservableVector<Object ^> ^>(navView->MenuItemsSource);
auto flatIndex = NavCategory::GetFlatIndex(ViewMode::Date);
navView->SelectedItem = menuItems->GetAt(flatIndex);
return;
}
auto currentHonorShortcuts = s_fHonorShortcuts.find(viewId);
auto currentHonorShortcuts = s_fHonorShortcuts.find(viewId);
auto currentIgnoreNextEscape = s_ignoreNextEscape.find(viewId);
@@ -615,9 +588,9 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow^ sender, KeyEventArgs^
{
RunFirstEnabledButtonCommand(buttons);
// Ctrl+C and Ctrl+V shifts focus to some button because of which enter doesn't work after copy/paste. So don't shift focus if Ctrl+C or Ctrl+V is pressed.
// When drop down is open, pressing escape shifts focus to clear button. So dont's shift focus if drop down is open.
// Ctrl+Insert is equivalent to Ctrl+C and Shift+Insert is equivalent to Ctrl+V
// Ctrl+C and Ctrl+V shifts focus to some button because of which enter doesn't work after copy/paste. So don't shift focus if Ctrl+C or Ctrl+V
// is pressed. When drop down is open, pressing escape shifts focus to clear button. So dont's shift focus if drop down is open. Ctrl+Insert is
// equivalent to Ctrl+C and Shift+Insert is equivalent to Ctrl+V
if (currentIsDropDownOpen != s_IsDropDownOpen.end() && !currentIsDropDownOpen->second)
{
// Do not Light Up Buttons when Ctrl+C, Ctrl+V, Ctrl+Insert or Shift+Insert is pressed
@@ -632,7 +605,7 @@ void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow^ sender, KeyEventArgs^
}
}
void KeyboardShortcutManager::OnKeyUpHandler(CoreWindow^ sender, KeyEventArgs^ args)
void KeyboardShortcutManager::OnKeyUpHandler(CoreWindow ^ sender, KeyEventArgs ^ args)
{
int viewId = Utils::GetWindowId();
auto key = args->VirtualKey;
@@ -665,7 +638,7 @@ void KeyboardShortcutManager::OnKeyUpHandler(CoreWindow^ sender, KeyEventArgs^ a
}
}
void KeyboardShortcutManager::OnAcceleratorKeyActivated(CoreDispatcher^, AcceleratorKeyEventArgs^ args)
void KeyboardShortcutManager::OnAcceleratorKeyActivated(CoreDispatcher ^, AcceleratorKeyEventArgs ^ args)
{
if (args->KeyStatus.IsKeyReleased)
{
@@ -685,12 +658,12 @@ void KeyboardShortcutManager::OnAcceleratorKeyActivated(CoreDispatcher^, Acceler
auto item = listIterator->second.Resolve<MUXC::NavigationView>();
if (item != nullptr)
{
auto navView = safe_cast<MUXC::NavigationView^> (item);
auto navView = safe_cast<MUXC::NavigationView ^>(item);
auto menuItems = static_cast<IObservableVector<Object^>^>(navView->MenuItemsSource);
auto menuItems = static_cast<IObservableVector<Object ^> ^>(navView->MenuItemsSource);
if (menuItems != nullptr)
{
auto vm = safe_cast<ApplicationViewModel^>(navView->DataContext);
auto vm = safe_cast<ApplicationViewModel ^>(navView->DataContext);
if (nullptr != vm)
{
ViewMode toMode = NavCategory::GetViewModeForVirtualKey(static_cast<MyVirtualKey>(key));
@@ -722,13 +695,11 @@ void KeyboardShortcutManager::Initialize()
{
auto coreWindow = Window::Current->CoreWindow;
coreWindow->CharacterReceived +=
ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(&KeyboardShortcutManager::OnCharacterReceivedHandler);
coreWindow->KeyDown +=
ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(&KeyboardShortcutManager::OnKeyDownHandler);
coreWindow->KeyUp +=
ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(&KeyboardShortcutManager::OnKeyUpHandler);
ref new TypedEventHandler<CoreWindow ^, CharacterReceivedEventArgs ^>(&KeyboardShortcutManager::OnCharacterReceivedHandler);
coreWindow->KeyDown += ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(&KeyboardShortcutManager::OnKeyDownHandler);
coreWindow->KeyUp += ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(&KeyboardShortcutManager::OnKeyUpHandler);
coreWindow->Dispatcher->AcceleratorKeyActivated +=
ref new TypedEventHandler<CoreDispatcher^, AcceleratorKeyEventArgs^>(&KeyboardShortcutManager::OnAcceleratorKeyActivated);
ref new TypedEventHandler<CoreDispatcher ^, AcceleratorKeyEventArgs ^>(&KeyboardShortcutManager::OnAcceleratorKeyActivated);
KeyboardShortcutManager::RegisterNewAppViewId();
}
@@ -755,7 +726,7 @@ void KeyboardShortcutManager::UpdateDropDownState(bool isOpen)
}
}
void KeyboardShortcutManager::UpdateDropDownState(Flyout^ aboutPageFlyout)
void KeyboardShortcutManager::UpdateDropDownState(Flyout ^ aboutPageFlyout)
{
int viewId = Utils::GetWindowId();

View File

@@ -10,14 +10,17 @@ namespace CalculatorApp
{
namespace Common
{
public ref class KeyboardShortcutManager sealed
public
ref class KeyboardShortcutManager sealed
{
public:
KeyboardShortcutManager() {}
KeyboardShortcutManager()
{
}
DEPENDENCY_PROPERTY_OWNER(KeyboardShortcutManager);
DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(Platform::String^, Character);
DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(Platform::String ^, Character);
DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(MyVirtualKey, VirtualKey);
DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(MyVirtualKey, VirtualKeyControlChord);
DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(MyVirtualKey, VirtualKeyShiftChord);
@@ -26,9 +29,10 @@ namespace CalculatorApp
DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(MyVirtualKey, VirtualKeyInverseChord);
DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(MyVirtualKey, VirtualKeyControlInverseChord);
internal:
internal :
static void Initialize();
static void
Initialize();
// Sometimes, like with popups, escape is treated as special and even
// though it is handled we get it passed through to us. In those cases
@@ -42,57 +46,34 @@ namespace CalculatorApp
static void HandledEnter(bool ishandled);
static void UpdateDropDownState(bool);
static void ShiftButtonChecked(bool checked);
static void UpdateDropDownState(Windows::UI::Xaml::Controls::Flyout^ aboutPageFlyout);
static void UpdateDropDownState(Windows::UI::Xaml::Controls::Flyout ^ aboutPageFlyout);
static void RegisterNewAppViewId();
static void OnWindowClosed(int viewId);
private:
static void OnCharacterPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, Platform::String ^ oldValue, Platform::String ^ newValue);
static void OnCharacterPropertyChanged(
Windows::UI::Xaml::DependencyObject^ target,
Platform::String^ oldValue,
Platform::String^ newValue);
static void OnVirtualKeyPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, MyVirtualKey oldValue, MyVirtualKey newValue);
static void OnVirtualKeyPropertyChanged(
Windows::UI::Xaml::DependencyObject^ target,
MyVirtualKey oldValue,
MyVirtualKey newValue);
static void OnVirtualKeyControlChordPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, MyVirtualKey oldValue, MyVirtualKey newValue);
static void OnVirtualKeyControlChordPropertyChanged(
Windows::UI::Xaml::DependencyObject^ target,
MyVirtualKey oldValue,
MyVirtualKey newValue);
static void OnVirtualKeyShiftChordPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, MyVirtualKey oldValue, MyVirtualKey newValue);
static void OnVirtualKeyShiftChordPropertyChanged(
Windows::UI::Xaml::DependencyObject^ target,
MyVirtualKey oldValue,
MyVirtualKey newValue);
static void OnVirtualKeyInverseChordPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, MyVirtualKey oldValue, MyVirtualKey newValue);
static void OnVirtualKeyInverseChordPropertyChanged(
Windows::UI::Xaml::DependencyObject^ target,
MyVirtualKey oldValue,
MyVirtualKey newValue);
static void OnVirtualKeyControlInverseChordPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, MyVirtualKey oldValue,
MyVirtualKey newValue);
static void OnVirtualKeyControlInverseChordPropertyChanged(
Windows::UI::Xaml::DependencyObject^ target,
MyVirtualKey oldValue,
MyVirtualKey newValue);
static void OnVirtualKeyAltChordPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, MyVirtualKey oldValue, MyVirtualKey newValue);
static void OnVirtualKeyAltChordPropertyChanged(
Windows::UI::Xaml::DependencyObject^ target,
MyVirtualKey oldValue,
MyVirtualKey newValue);
static void OnVirtualKeyControlShiftChordPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, MyVirtualKey oldValue,
MyVirtualKey newValue);
static void OnVirtualKeyControlShiftChordPropertyChanged(
Windows::UI::Xaml::DependencyObject^ target,
MyVirtualKey oldValue,
MyVirtualKey newValue);
static void OnCharacterReceivedHandler(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args);
static void OnKeyDownHandler(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
static void OnKeyUpHandler(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
static void OnAcceleratorKeyActivated(Windows::UI::Core::CoreDispatcher^, Windows::UI::Core::AcceleratorKeyEventArgs^ args);
static void OnCharacterReceivedHandler(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::CharacterReceivedEventArgs ^ args);
static void OnKeyDownHandler(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args);
static void OnKeyUpHandler(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args);
static void OnAcceleratorKeyActivated(Windows::UI::Core::CoreDispatcher ^, Windows::UI::Core::AcceleratorKeyEventArgs ^ args);
};
}
}

View File

@@ -33,16 +33,15 @@ DEPENDENCY_PROPERTY_INITIALIZATION(LocalizationService, FontSize);
static reader_writer_lock s_locServiceInstanceLock;
LocalizationService^ LocalizationService::s_singletonInstance = nullptr;
LocalizationService ^ LocalizationService::s_singletonInstance = nullptr;
// Resources for the engine use numbers as keys. It's inconvenient, but also difficult to
// change given that the engine heavily relies on perfect ordering of certain elements.
// The key for open parenthesis, '(', is "48".
static constexpr auto s_openParenResourceKey = L"48";
LocalizationService^ LocalizationService::GetInstance()
LocalizationService ^ LocalizationService::GetInstance()
{
if (s_singletonInstance == nullptr)
{
// Writer lock for the static maps
@@ -59,20 +58,20 @@ LocalizationService^ LocalizationService::GetInstance()
LocalizationService::LocalizationService()
{
m_language = ApplicationLanguages::Languages->GetAt(0);
m_flowDirection = ResourceContext::GetForCurrentView()->QualifierValues->Lookup(L"LayoutDirection")
!= L"LTR" ? FlowDirection::RightToLeft : FlowDirection::LeftToRight;
m_flowDirection =
ResourceContext::GetForCurrentView()->QualifierValues->Lookup(L"LayoutDirection") != L"LTR" ? FlowDirection::RightToLeft : FlowDirection::LeftToRight;
auto resourceLoader = AppResourceProvider::GetInstance();
m_fontFamilyOverride = resourceLoader.GetResourceString(L"LocalizedFontFamilyOverride");
String^ reserved = L"RESERVED_FOR_FONTLOC";
String ^ reserved = L"RESERVED_FOR_FONTLOC";
m_overrideFontApiValues = ((m_fontFamilyOverride != nullptr) && (m_fontFamilyOverride != reserved));
if (m_overrideFontApiValues)
{
String^ localizedUICaptionFontSizeFactorOverride = resourceLoader.GetResourceString(L"LocalizedUICaptionFontSizeFactorOverride");
String^ localizedUITextFontSizeFactorOverride = resourceLoader.GetResourceString(L"LocalizedUITextFontSizeFactorOverride");
String^ localizedFontWeightOverride = resourceLoader.GetResourceString(L"LocalizedFontWeightOverride");
String ^ localizedUICaptionFontSizeFactorOverride = resourceLoader.GetResourceString(L"LocalizedUICaptionFontSizeFactorOverride");
String ^ localizedUITextFontSizeFactorOverride = resourceLoader.GetResourceString(L"LocalizedUITextFontSizeFactorOverride");
String ^ localizedFontWeightOverride = resourceLoader.GetResourceString(L"LocalizedFontWeightOverride");
// If any of the font overrides are modified then all of them need to be modified
assert(localizedFontWeightOverride != reserved);
@@ -87,7 +86,7 @@ LocalizationService::LocalizationService()
m_fontGroup = ref new LanguageFontGroup(m_language);
}
FontWeight LocalizationService::ParseFontWeight(String^ fontWeight)
FontWeight LocalizationService::ParseFontWeight(String ^ fontWeight)
{
wstring weight = fontWeight->Data();
transform(weight.begin(), weight.end(), weight.begin(), towlower);
@@ -153,7 +152,7 @@ bool LocalizationService::IsRtlLayout()
return m_flowDirection == FlowDirection::RightToLeft;
}
String^ LocalizationService::GetLanguage()
String ^ LocalizationService::GetLanguage()
{
return m_language;
}
@@ -163,7 +162,7 @@ bool LocalizationService::GetOverrideFontApiValues()
return m_overrideFontApiValues;
}
FontFamily^ LocalizationService::GetLanguageFontFamilyForType(LanguageFontType fontType)
FontFamily ^ LocalizationService::GetLanguageFontFamilyForType(LanguageFontType fontType)
{
if (m_overrideFontApiValues)
{
@@ -175,7 +174,7 @@ FontFamily^ LocalizationService::GetLanguageFontFamilyForType(LanguageFontType f
}
}
LanguageFont^ LocalizationService::GetLanguageFont(LanguageFontType fontType)
LanguageFont ^ LocalizationService::GetLanguageFont(LanguageFontType fontType)
{
assert(!m_overrideFontApiValues);
assert(m_fontGroup);
@@ -191,7 +190,7 @@ LanguageFont^ LocalizationService::GetLanguageFont(LanguageFontType fontType)
}
}
String^ LocalizationService::GetFontFamilyOverride()
String ^ LocalizationService::GetFontFamilyOverride()
{
assert(m_overrideFontApiValues);
return m_fontFamilyOverride;
@@ -218,24 +217,24 @@ double LocalizationService::GetFontScaleFactorOverride(LanguageFontType fontType
}
}
void LocalizationService::OnFontTypePropertyChanged(DependencyObject^ target, LanguageFontType /*oldValue*/, LanguageFontType /*newValue*/)
void LocalizationService::OnFontTypePropertyChanged(DependencyObject ^ target, LanguageFontType /*oldValue*/, LanguageFontType /*newValue*/)
{
UpdateFontFamilyAndSize(target);
}
void LocalizationService::OnFontWeightPropertyChanged(DependencyObject^ target, FontWeight /*oldValue*/, FontWeight /*newValue*/)
void LocalizationService::OnFontWeightPropertyChanged(DependencyObject ^ target, FontWeight /*oldValue*/, FontWeight /*newValue*/)
{
UpdateFontFamilyAndSize(target);
}
void LocalizationService::OnFontSizePropertyChanged(DependencyObject^ target, double /*oldValue*/, double /*newValue*/)
void LocalizationService::OnFontSizePropertyChanged(DependencyObject ^ target, double /*oldValue*/, double /*newValue*/)
{
UpdateFontFamilyAndSize(target);
}
void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target)
void LocalizationService::UpdateFontFamilyAndSize(DependencyObject ^ target)
{
FontFamily^ fontFamily;
FontFamily ^ fontFamily;
FontWeight fontWeight;
bool fOverrideFontWeight = false;
double scaleFactor;
@@ -259,7 +258,7 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target)
double sizeToUse = LocalizationService::GetFontSize(target) * scaleFactor;
auto control = dynamic_cast<Control^>(target);
auto control = dynamic_cast<Control ^>(target);
if (control)
{
control->FontFamily = fontFamily;
@@ -278,7 +277,7 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target)
}
else
{
auto textBlock = dynamic_cast<TextBlock^>(target);
auto textBlock = dynamic_cast<TextBlock ^>(target);
if (textBlock)
{
textBlock->FontFamily = fontFamily;
@@ -297,7 +296,7 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target)
}
else
{
RichTextBlock^ richTextBlock = dynamic_cast<RichTextBlock^>(target);
RichTextBlock ^ richTextBlock = dynamic_cast<RichTextBlock ^>(target);
if (richTextBlock)
{
richTextBlock->FontFamily = fontFamily;
@@ -316,7 +315,7 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target)
}
else
{
TextElement^ textElement = dynamic_cast<TextElement^>(target);
TextElement ^ textElement = dynamic_cast<TextElement ^>(target);
if (textElement)
{
textElement->FontFamily = fontFamily;
@@ -340,9 +339,9 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject^ target)
// If successful, returns a formatter that respects the user's regional format settings,
// as configured by running intl.cpl.
DecimalFormatter^ LocalizationService::GetRegionalSettingsAwareDecimalFormatter()
DecimalFormatter ^ LocalizationService::GetRegionalSettingsAwareDecimalFormatter()
{
IIterable<String^>^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
IIterable<String ^> ^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
if (languageIdentifiers != nullptr)
{
return ref new DecimalFormatter(languageIdentifiers, GlobalizationPreferences::HomeGeographicRegion);
@@ -355,9 +354,9 @@ DecimalFormatter^ LocalizationService::GetRegionalSettingsAwareDecimalFormatter(
// as configured by running intl.cpl.
//
// This helper function creates a DateTimeFormatter with a TwentyFour hour clock
DateTimeFormatter^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(_In_ String^ format)
DateTimeFormatter ^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(_In_ String ^ format)
{
IIterable<String^>^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
IIterable<String ^> ^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
if (languageIdentifiers == nullptr)
{
languageIdentifiers = ApplicationLanguages::Languages;
@@ -368,41 +367,30 @@ DateTimeFormatter^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatte
// If successful, returns a formatter that respects the user's regional format settings,
// as configured by running intl.cpl.
DateTimeFormatter^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(
_In_ String^ format,
_In_ String^ calendarIdentifier,
_In_ String^ clockIdentifier)
DateTimeFormatter
^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(_In_ String ^ format, _In_ String ^ calendarIdentifier, _In_ String ^ clockIdentifier)
{
IIterable<String^>^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
IIterable<String ^> ^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
if (languageIdentifiers == nullptr)
{
languageIdentifiers = ApplicationLanguages::Languages;
}
return ref new DateTimeFormatter(
format,
languageIdentifiers,
GlobalizationPreferences::HomeGeographicRegion,
calendarIdentifier,
clockIdentifier);
return ref new DateTimeFormatter(format, languageIdentifiers, GlobalizationPreferences::HomeGeographicRegion, calendarIdentifier, clockIdentifier);
}
CurrencyFormatter^ LocalizationService::GetRegionalSettingsAwareCurrencyFormatter()
CurrencyFormatter ^ LocalizationService::GetRegionalSettingsAwareCurrencyFormatter()
{
String^ userCurrency = (GlobalizationPreferences::Currencies->Size > 0)
? GlobalizationPreferences::Currencies->GetAt(0)
: StringReference(DefaultCurrencyCode.data());
String ^ userCurrency =
(GlobalizationPreferences::Currencies->Size > 0) ? GlobalizationPreferences::Currencies->GetAt(0) : StringReference(DefaultCurrencyCode.data());
IIterable<String^>^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
IIterable<String ^> ^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
if (languageIdentifiers == nullptr)
{
languageIdentifiers = ApplicationLanguages::Languages;
}
auto currencyFormatter = ref new CurrencyFormatter(
userCurrency,
languageIdentifiers,
GlobalizationPreferences::HomeGeographicRegion);
auto currencyFormatter = ref new CurrencyFormatter(userCurrency, languageIdentifiers, GlobalizationPreferences::HomeGeographicRegion);
int fractionDigits = LocalizationSettings::GetInstance().GetCurrencyTrailingDigits();
currencyFormatter->FractionDigits = fractionDigits;
@@ -410,7 +398,7 @@ CurrencyFormatter^ LocalizationService::GetRegionalSettingsAwareCurrencyFormatte
return currencyFormatter;
}
IIterable<String^>^ LocalizationService::GetLanguageIdentifiers()
IIterable<String ^> ^ LocalizationService::GetLanguageIdentifiers()
{
WCHAR currentLocale[LOCALE_NAME_MAX_LENGTH] = {};
int result = GetUserDefaultLocaleName(currentLocale, LOCALE_NAME_MAX_LENGTH);
@@ -426,12 +414,12 @@ IIterable<String^>^ LocalizationService::GetLanguageIdentifiers()
*underscore = L'\0';
}
String^ localeString = ref new String(currentLocale);
String ^ localeString = ref new String(currentLocale);
// validate if the locale we have is valid
// otherwise we fallback to the default.
if (Language::IsWellFormed(localeString))
{
auto languageList = ref new Vector<String^>();
auto languageList = ref new Vector<String ^>();
languageList->Append(localeString);
return languageList;
}
@@ -448,49 +436,34 @@ unordered_map<wstring, wstring> LocalizationService::GetTokenToReadableNameMap()
// standard project resources.
static vector<pair<wstring, wstring>> s_parenEngineKeyResourceMap = {
// Sine permutations
make_pair<wstring, wstring>(L"67", L"SineDegrees"),
make_pair<wstring, wstring>(L"73", L"SineRadians"),
make_pair<wstring, wstring>(L"79", L"SineGradians"),
make_pair<wstring, wstring>(L"70", L"InverseSineDegrees"),
make_pair<wstring, wstring>(L"76", L"InverseSineRadians"),
make_pair<wstring, wstring>(L"82", L"InverseSineGradians"),
make_pair<wstring, wstring>(L"25", L"HyperbolicSine"),
make_pair<wstring, wstring>(L"85", L"InverseHyperbolicSine"),
make_pair<wstring, wstring>(L"67", L"SineDegrees"), make_pair<wstring, wstring>(L"73", L"SineRadians"),
make_pair<wstring, wstring>(L"79", L"SineGradians"), make_pair<wstring, wstring>(L"70", L"InverseSineDegrees"),
make_pair<wstring, wstring>(L"76", L"InverseSineRadians"), make_pair<wstring, wstring>(L"82", L"InverseSineGradians"),
make_pair<wstring, wstring>(L"25", L"HyperbolicSine"), make_pair<wstring, wstring>(L"85", L"InverseHyperbolicSine"),
// Cosine permutations
make_pair<wstring, wstring>(L"68", L"CosineDegrees"),
make_pair<wstring, wstring>(L"74", L"CosineRadians"),
make_pair<wstring, wstring>(L"80", L"CosineGradians"),
make_pair<wstring, wstring>(L"71", L"InverseCosineDegrees"),
make_pair<wstring, wstring>(L"77", L"InverseCosineRadians"),
make_pair<wstring, wstring>(L"83", L"InverseCosineGradians"),
make_pair<wstring, wstring>(L"26", L"HyperbolicCosine"),
make_pair<wstring, wstring>(L"86", L"InverseHyperbolicCosine"),
make_pair<wstring, wstring>(L"68", L"CosineDegrees"), make_pair<wstring, wstring>(L"74", L"CosineRadians"),
make_pair<wstring, wstring>(L"80", L"CosineGradians"), make_pair<wstring, wstring>(L"71", L"InverseCosineDegrees"),
make_pair<wstring, wstring>(L"77", L"InverseCosineRadians"), make_pair<wstring, wstring>(L"83", L"InverseCosineGradians"),
make_pair<wstring, wstring>(L"26", L"HyperbolicCosine"), make_pair<wstring, wstring>(L"86", L"InverseHyperbolicCosine"),
// Tangent permutations
make_pair<wstring, wstring>(L"69", L"TangentDegrees"),
make_pair<wstring, wstring>(L"75", L"TangentRadians"),
make_pair<wstring, wstring>(L"81", L"TangentGradians"),
make_pair<wstring, wstring>(L"72", L"InverseTangentDegrees"),
make_pair<wstring, wstring>(L"78", L"InverseTangentRadians"),
make_pair<wstring, wstring>(L"84", L"InverseTangentGradians"),
make_pair<wstring, wstring>(L"27", L"HyperbolicTangent"),
make_pair<wstring, wstring>(L"87", L"InverseHyperbolicTangent"),
make_pair<wstring, wstring>(L"69", L"TangentDegrees"), make_pair<wstring, wstring>(L"75", L"TangentRadians"),
make_pair<wstring, wstring>(L"81", L"TangentGradians"), make_pair<wstring, wstring>(L"72", L"InverseTangentDegrees"),
make_pair<wstring, wstring>(L"78", L"InverseTangentRadians"), make_pair<wstring, wstring>(L"84", L"InverseTangentGradians"),
make_pair<wstring, wstring>(L"27", L"HyperbolicTangent"), make_pair<wstring, wstring>(L"87", L"InverseHyperbolicTangent"),
// Miscellaneous Scientific functions
make_pair<wstring, wstring>(L"94", L"Factorial"),
make_pair<wstring, wstring>(L"35", L"DegreeMinuteSecond"),
make_pair<wstring, wstring>(L"28", L"NaturalLog"),
make_pair<wstring, wstring>(L"91", L"Square")
make_pair<wstring, wstring>(L"94", L"Factorial"), make_pair<wstring, wstring>(L"35", L"DegreeMinuteSecond"),
make_pair<wstring, wstring>(L"28", L"NaturalLog"), make_pair<wstring, wstring>(L"91", L"Square")
};
static vector<pair<wstring, wstring>> s_noParenEngineKeyResourceMap = {
// Programmer mode functions
make_pair<wstring, wstring>(L"9", L"LeftShift"),
make_pair<wstring, wstring>(L"10", L"RightShift"),
static vector<pair<wstring, wstring>> s_noParenEngineKeyResourceMap = { // Programmer mode functions
make_pair<wstring, wstring>(L"9", L"LeftShift"),
make_pair<wstring, wstring>(L"10", L"RightShift"),
// Y Root scientific function
make_pair<wstring, wstring>(L"16", L"YRoot")
// Y Root scientific function
make_pair<wstring, wstring>(L"16", L"YRoot")
};
unordered_map<wstring, wstring> tokenToReadableNameMap{};
@@ -523,7 +496,7 @@ unordered_map<wstring, wstring> LocalizationService::GetTokenToReadableNameMap()
return tokenToReadableNameMap;
}
String^ LocalizationService::GetNarratorReadableToken(String^ rawToken)
String ^ LocalizationService::GetNarratorReadableToken(String ^ rawToken)
{
static unordered_map<wstring, wstring> s_tokenToReadableNameMap = GetTokenToReadableNameMap();
@@ -534,12 +507,12 @@ String^ LocalizationService::GetNarratorReadableToken(String^ rawToken)
}
else
{
static const String^ openParen = AppResourceProvider::GetInstance().GetCEngineString(StringReference(s_openParenResourceKey));
static const String ^ openParen = AppResourceProvider::GetInstance().GetCEngineString(StringReference(s_openParenResourceKey));
return ref new String(itr->second.c_str()) + L" " + openParen;
}
}
String^ LocalizationService::GetNarratorReadableString(String^ rawString)
String ^ LocalizationService::GetNarratorReadableString(String ^ rawString)
{
wstringstream readableString{};
readableString << L"";

View File

@@ -5,81 +5,83 @@
#include "Utils.h"
namespace CalculatorApp { namespace Common
namespace CalculatorApp
{
namespace LocalizationServiceProperties
namespace Common
{
static constexpr std::wstring_view DefaultCurrencyCode{ L"USD" };
namespace LocalizationServiceProperties
{
static constexpr std::wstring_view DefaultCurrencyCode{ L"USD" };
}
public
enum class LanguageFontType
{
UIText,
UICaption,
};
public
ref class LocalizationService sealed
{
public:
DEPENDENCY_PROPERTY_OWNER(LocalizationService);
DEPENDENCY_PROPERTY_ATTACHED_WITH_DEFAULT_AND_CALLBACK(LanguageFontType, FontType, LanguageFontType::UIText);
DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(double, FontSize);
internal : static LocalizationService ^ GetInstance();
Windows::UI::Xaml::FlowDirection GetFlowDirection();
bool IsRtlLayout();
bool GetOverrideFontApiValues();
Platform::String ^ GetLanguage();
Windows::UI::Xaml::Media::FontFamily ^ GetLanguageFontFamilyForType(LanguageFontType fontType);
Platform::String ^ GetFontFamilyOverride();
Windows::UI::Text::FontWeight GetFontWeightOverride();
double GetFontScaleFactorOverride(LanguageFontType fontType);
static Windows::Globalization::NumberFormatting::DecimalFormatter ^ GetRegionalSettingsAwareDecimalFormatter();
static Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ GetRegionalSettingsAwareDateTimeFormatter(_In_ Platform::String ^ format);
static Windows::Globalization::DateTimeFormatting::DateTimeFormatter
^ GetRegionalSettingsAwareDateTimeFormatter(_In_ Platform::String ^ format, _In_ Platform::String ^ calendarIdentifier,
_In_ Platform::String ^ clockIdentifier);
static Windows::Globalization::NumberFormatting::CurrencyFormatter ^ GetRegionalSettingsAwareCurrencyFormatter();
static Platform::String ^ GetNarratorReadableToken(Platform::String ^ rawToken);
static Platform::String ^ GetNarratorReadableString(Platform::String ^ rawString);
private:
Windows::Globalization::Fonts::LanguageFont ^ GetLanguageFont(LanguageFontType fontType);
Windows::UI::Text::FontWeight ParseFontWeight(Platform::String ^ fontWeight);
static Windows::Foundation::Collections::IIterable<Platform::String ^> ^ GetLanguageIdentifiers();
// Attached property callbacks
static void OnFontTypePropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, LanguageFontType oldValue, LanguageFontType newValue);
static void OnFontWeightPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, Windows::UI::Text::FontWeight oldValue,
Windows::UI::Text::FontWeight newValue);
static void OnFontSizePropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, double oldValue, double newValue);
static void UpdateFontFamilyAndSize(Windows::UI::Xaml::DependencyObject ^ target);
static std::unordered_map<std::wstring, std::wstring> GetTokenToReadableNameMap();
private:
LocalizationService();
static LocalizationService ^ s_singletonInstance;
Windows::Globalization::Fonts::LanguageFontGroup ^ m_fontGroup;
Platform::String ^ m_language;
Windows::UI::Xaml::FlowDirection m_flowDirection;
bool m_overrideFontApiValues;
Platform::String ^ m_fontFamilyOverride;
Windows::UI::Text::FontWeight m_fontWeightOverride;
double m_uiTextFontScaleFactorOverride;
double m_uiCaptionFontScaleFactorOverride;
};
}
public enum class LanguageFontType
{
UIText,
UICaption,
};
public ref class LocalizationService sealed
{
public:
DEPENDENCY_PROPERTY_OWNER(LocalizationService);
DEPENDENCY_PROPERTY_ATTACHED_WITH_DEFAULT_AND_CALLBACK(LanguageFontType, FontType, LanguageFontType::UIText);
DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(double, FontSize);
internal:
static LocalizationService^ GetInstance();
Windows::UI::Xaml::FlowDirection GetFlowDirection();
bool IsRtlLayout();
bool GetOverrideFontApiValues();
Platform::String^ GetLanguage();
Windows::UI::Xaml::Media::FontFamily^ GetLanguageFontFamilyForType(LanguageFontType fontType);
Platform::String^ GetFontFamilyOverride();
Windows::UI::Text::FontWeight GetFontWeightOverride();
double GetFontScaleFactorOverride(LanguageFontType fontType);
static Windows::Globalization::NumberFormatting::DecimalFormatter^ GetRegionalSettingsAwareDecimalFormatter();
static Windows::Globalization::DateTimeFormatting::DateTimeFormatter^ GetRegionalSettingsAwareDateTimeFormatter(_In_ Platform::String^ format);
static Windows::Globalization::DateTimeFormatting::DateTimeFormatter^ GetRegionalSettingsAwareDateTimeFormatter(
_In_ Platform::String^ format,
_In_ Platform::String^ calendarIdentifier,
_In_ Platform::String^ clockIdentifier);
static Windows::Globalization::NumberFormatting::CurrencyFormatter^ GetRegionalSettingsAwareCurrencyFormatter();
static Platform::String^ GetNarratorReadableToken(Platform::String^ rawToken);
static Platform::String^ GetNarratorReadableString(Platform::String^ rawString);
private:
Windows::Globalization::Fonts::LanguageFont^ GetLanguageFont(LanguageFontType fontType);
Windows::UI::Text::FontWeight ParseFontWeight(Platform::String^ fontWeight);
static Windows::Foundation::Collections::IIterable<Platform::String^>^ GetLanguageIdentifiers();
// Attached property callbacks
static void OnFontTypePropertyChanged(Windows::UI::Xaml::DependencyObject^ target, LanguageFontType oldValue, LanguageFontType newValue);
static void OnFontWeightPropertyChanged(Windows::UI::Xaml::DependencyObject^ target, Windows::UI::Text::FontWeight oldValue, Windows::UI::Text::FontWeight newValue);
static void OnFontSizePropertyChanged(Windows::UI::Xaml::DependencyObject^ target, double oldValue, double newValue);
static void UpdateFontFamilyAndSize(Windows::UI::Xaml::DependencyObject^ target);
static std::unordered_map<std::wstring, std::wstring> GetTokenToReadableNameMap();
private:
LocalizationService();
static LocalizationService^ s_singletonInstance;
Windows::Globalization::Fonts::LanguageFontGroup^ m_fontGroup;
Platform::String^ m_language;
Windows::UI::Xaml::FlowDirection m_flowDirection;
bool m_overrideFontApiValues;
Platform::String^ m_fontFamilyOverride;
Windows::UI::Text::FontWeight m_fontWeightOverride;
double m_uiTextFontScaleFactorOverride;
double m_uiCaptionFontScaleFactorOverride;
};
}}
}

View File

@@ -18,7 +18,7 @@ namespace CalculatorApp
int result = 0;
// Use DecimalFormatter as it respects the locale and the user setting
Windows::Globalization::NumberFormatting::DecimalFormatter^ formatter;
Windows::Globalization::NumberFormatting::DecimalFormatter ^ formatter;
formatter = CalculatorApp::Common::LocalizationService::GetRegionalSettingsAwareDecimalFormatter();
formatter->FractionDigits = 0;
formatter->IsDecimalPointAlwaysDisplayed = false;
@@ -29,9 +29,7 @@ namespace CalculatorApp
}
wchar_t resolvedName[LOCALE_NAME_MAX_LENGTH];
result = ResolveLocaleName(formatter->ResolvedLanguage->Data(),
resolvedName,
LOCALE_NAME_MAX_LENGTH);
result = ResolveLocaleName(formatter->ResolvedLanguage->Data(), resolvedName, LOCALE_NAME_MAX_LENGTH);
if (result == 0)
{
throw std::runtime_error("Unexpected error resolving locale name");
@@ -40,30 +38,21 @@ namespace CalculatorApp
{
m_resolvedName = resolvedName;
wchar_t decimalString[LocaleSettingBufferSize] = L"";
result = GetLocaleInfoEx(m_resolvedName.c_str(),
LOCALE_SDECIMAL,
decimalString,
static_cast<int>(std::size(decimalString)));
result = GetLocaleInfoEx(m_resolvedName.c_str(), LOCALE_SDECIMAL, decimalString, static_cast<int>(std::size(decimalString)));
if (result == 0)
{
throw std::runtime_error("Unexpected error while getting locale info");
}
wchar_t groupingSymbolString[LocaleSettingBufferSize] = L"";
result = GetLocaleInfoEx(m_resolvedName.c_str(),
LOCALE_STHOUSAND,
groupingSymbolString,
static_cast<int>(std::size(groupingSymbolString)));
result = GetLocaleInfoEx(m_resolvedName.c_str(), LOCALE_STHOUSAND, groupingSymbolString, static_cast<int>(std::size(groupingSymbolString)));
if (result == 0)
{
throw std::runtime_error("Unexpected error while getting locale info");
}
wchar_t numberGroupingString[LocaleSettingBufferSize] = L"";
result = GetLocaleInfoEx(m_resolvedName.c_str(),
LOCALE_SGROUPING,
numberGroupingString,
static_cast<int>(std::size(numberGroupingString)));
result = GetLocaleInfoEx(m_resolvedName.c_str(), LOCALE_SGROUPING, numberGroupingString, static_cast<int>(std::size(numberGroupingString)));
if (result == 0)
{
throw std::runtime_error("Unexpected error while getting locale info");
@@ -71,20 +60,16 @@ namespace CalculatorApp
// Get locale info for List Separator, eg. comma is used in many locales
wchar_t listSeparatorString[4] = L"";
result = ::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
LOCALE_SLIST,
listSeparatorString,
static_cast<int>(std::size(listSeparatorString))); // Max length of the expected return value is 4
result = ::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SLIST, listSeparatorString,
static_cast<int>(std::size(listSeparatorString))); // Max length of the expected return value is 4
if (result == 0)
{
throw std::runtime_error("Unexpected error while getting locale info");
}
int currencyTrailingDigits = 0;
result = GetLocaleInfoEx(m_resolvedName.c_str(),
LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER,
(LPWSTR)&currencyTrailingDigits,
sizeof(currencyTrailingDigits) / sizeof(WCHAR));
result = GetLocaleInfoEx(m_resolvedName.c_str(), LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER, (LPWSTR)&currencyTrailingDigits,
sizeof(currencyTrailingDigits) / sizeof(WCHAR));
if (result == 0)
{
throw std::runtime_error("Unexpected error while getting locale info");
@@ -93,10 +78,8 @@ namespace CalculatorApp
// Currency symbol precedence is either 0 or 1.
// A value of 0 indicates the symbol follows the currency value.
int currencySymbolPrecedence = 1;
result = GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
LOCALE_IPOSSYMPRECEDES | LOCALE_RETURN_NUMBER,
(LPWSTR)&currencySymbolPrecedence,
sizeof(currencySymbolPrecedence) / sizeof(WCHAR));
result = GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_IPOSSYMPRECEDES | LOCALE_RETURN_NUMBER, (LPWSTR)&currencySymbolPrecedence,
sizeof(currencySymbolPrecedence) / sizeof(WCHAR));
// As CalcEngine only supports the first character of the decimal separator,
// Only first character of the decimal separator string is supported.
@@ -112,24 +95,21 @@ namespace CalculatorApp
// Note: This function returns 0 on failure.
// We'll ignore the failure in that case and the CalendarIdentifier would get set to GregorianCalendar.
CALID calId;
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER,
reinterpret_cast<PWSTR>(&calId),
sizeof(calId));
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER, reinterpret_cast<PWSTR>(&calId), sizeof(calId));
m_calendarIdentifier = GetCalendarIdentifierFromCalid(calId);
// Get FirstDayOfWeek Date and Time setting
wchar_t day[80] = L"";
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
LOCALE_IFIRSTDAYOFWEEK, // The first day in a week
reinterpret_cast<PWSTR>(day), // Argument is of type PWSTR
static_cast<int>(std::size(day))); // Max return size are 80 characters
LOCALE_IFIRSTDAYOFWEEK, // The first day in a week
reinterpret_cast<PWSTR>(day), // Argument is of type PWSTR
static_cast<int>(std::size(day))); // Max return size are 80 characters
// The LOCALE_IFIRSTDAYOFWEEK integer value varies from 0, 1, .. 6 for Monday, Tuesday, ... Sunday
// DayOfWeek enum value varies from 0, 1, .. 6 for Sunday, Monday, ... Saturday
// Hence, DayOfWeek = (valueof(LOCALE_IFIRSTDAYOFWEEK) + 1) % 7
m_firstDayOfWeek = static_cast<Windows::Globalization::DayOfWeek>((_wtoi(day) + 1) % 7); // static cast int to DayOfWeek enum
m_firstDayOfWeek = static_cast<Windows::Globalization::DayOfWeek>((_wtoi(day) + 1) % 7); // static cast int to DayOfWeek enum
}
public:
@@ -149,7 +129,7 @@ namespace CalculatorApp
return localizationSettings;
}
Platform::String^ GetLocaleName() const
Platform::String ^ GetLocaleName() const
{
return ref new Platform::String(m_resolvedName.c_str());
}
@@ -179,7 +159,7 @@ namespace CalculatorApp
}
}
Platform::String^ GetEnglishValueFromLocalizedDigits(const std::wstring& localizedString) const
Platform::String ^ GetEnglishValueFromLocalizedDigits(const std::wstring& localizedString) const
{
if (m_resolvedName == L"en-US")
{
@@ -201,7 +181,7 @@ namespace CalculatorApp
{
ch = j.ToString()->Data()[0];
break;
//ch = val - L'0';
// ch = val - L'0';
}
}
}
@@ -305,7 +285,7 @@ namespace CalculatorApp
}
}
Platform::String^ GetCalendarIdentifier() const
Platform::String ^ GetCalendarIdentifier() const
{
return m_calendarIdentifier;
}
@@ -378,7 +358,7 @@ namespace CalculatorApp
// Hexadecimal characters are not currently localized
static constexpr std::array<wchar_t, 6> s_hexSymbols{ L'A', L'B', L'C', L'D', L'E', L'F' };
std::wstring m_listSeparator;
Platform::String^ m_calendarIdentifier;
Platform::String ^ m_calendarIdentifier;
Windows::Globalization::DayOfWeek m_firstDayOfWeek;
int m_currencySymbolPrecedence;
std::wstring m_resolvedName;

View File

@@ -19,13 +19,7 @@ namespace CalculatorApp
std::unique_ptr<wchar_t[]> spBuffer = std::unique_ptr<wchar_t[]>(new wchar_t[length]);
va_list args = NULL;
va_start(args, pMessage);
DWORD fmtReturnVal = FormatMessage(FORMAT_MESSAGE_FROM_STRING,
pMessage,
0,
0,
spBuffer.get(),
length,
&args);
DWORD fmtReturnVal = FormatMessage(FORMAT_MESSAGE_FROM_STRING, pMessage, 0, 0, spBuffer.get(), length, &args);
va_end(args);
if (fmtReturnVal != 0)

View File

@@ -7,7 +7,8 @@ namespace CalculatorApp
{
namespace Common
{
public enum class MyVirtualKey
public
enum class MyVirtualKey
{
None = 0,
LeftButton = 1,

View File

@@ -24,80 +24,89 @@ static constexpr bool POSITIVE_ONLY = false;
// The order of items in this list determines the order of groups in the menu.
static constexpr array<const NavCategoryGroupInitializer, 2> s_categoryGroupManifest = {
NavCategoryGroupInitializer { CategoryGroupType::Calculator, L"CalculatorModeTextCaps", L"CalculatorModeText", L"CalculatorModePluralText"},
NavCategoryGroupInitializer { CategoryGroupType::Converter, L"ConverterModeTextCaps", L"ConverterModeText", L"ConverterModePluralText" }
NavCategoryGroupInitializer{ CategoryGroupType::Calculator, L"CalculatorModeTextCaps", L"CalculatorModeText", L"CalculatorModePluralText" },
NavCategoryGroupInitializer{ CategoryGroupType::Converter, L"ConverterModeTextCaps", L"ConverterModeText", L"ConverterModePluralText" }
};
// vvv THESE CONSTANTS SHOULD NEVER CHANGE vvv
static constexpr int STANDARD_ID = 0;
static constexpr int SCIENTIFIC_ID = 1;
static constexpr int PROGRAMMER_ID = 2;
static constexpr int DATE_ID = 3;
static constexpr int VOLUME_ID = 4;
static constexpr int LENGTH_ID = 5;
static constexpr int WEIGHT_ID = 6;
static constexpr int STANDARD_ID = 0;
static constexpr int SCIENTIFIC_ID = 1;
static constexpr int PROGRAMMER_ID = 2;
static constexpr int DATE_ID = 3;
static constexpr int VOLUME_ID = 4;
static constexpr int LENGTH_ID = 5;
static constexpr int WEIGHT_ID = 6;
static constexpr int TEMPERATURE_ID = 7;
static constexpr int ENERGY_ID = 8;
static constexpr int AREA_ID = 9;
static constexpr int SPEED_ID = 10;
static constexpr int TIME_ID = 11;
static constexpr int POWER_ID = 12;
static constexpr int DATA_ID = 13;
static constexpr int PRESSURE_ID = 14;
static constexpr int ANGLE_ID = 15;
static constexpr int CURRENCY_ID = 16;
static constexpr int ENERGY_ID = 8;
static constexpr int AREA_ID = 9;
static constexpr int SPEED_ID = 10;
static constexpr int TIME_ID = 11;
static constexpr int POWER_ID = 12;
static constexpr int DATA_ID = 13;
static constexpr int PRESSURE_ID = 14;
static constexpr int ANGLE_ID = 15;
static constexpr int CURRENCY_ID = 16;
// ^^^ THESE CONSTANTS SHOULD NEVER CHANGE ^^^
// The order of items in this list determines the order of items in the menu.
static constexpr array<const NavCategoryInitializer, 17> s_categoryManifest = {
NavCategoryInitializer { ViewMode::Standard, STANDARD_ID, L"Standard", L"StandardMode", L"\uE8EF", CategoryGroupType::Calculator, MyVirtualKey::Number1, SUPPORTS_ALL },
NavCategoryInitializer { ViewMode::Scientific, SCIENTIFIC_ID, L"Scientific", L"ScientificMode", L"\uF196", CategoryGroupType::Calculator, MyVirtualKey::Number2, SUPPORTS_ALL },
NavCategoryInitializer { ViewMode::Programmer, PROGRAMMER_ID, L"Programmer", L"ProgrammerMode", L"\uECCE", CategoryGroupType::Calculator, MyVirtualKey::Number3, SUPPORTS_ALL },
NavCategoryInitializer { ViewMode::Date, DATE_ID, L"Date", L"DateCalculationMode", L"\uE787", CategoryGroupType::Calculator, MyVirtualKey::Number4, SUPPORTS_ALL },
NavCategoryInitializer { ViewMode::Currency, CURRENCY_ID, L"Currency", L"CategoryName_Currency", L"\uEB0D", CategoryGroupType::Converter, MyVirtualKey::None, POSITIVE_ONLY },
NavCategoryInitializer { ViewMode::Volume, VOLUME_ID, L"Volume", L"CategoryName_Volume", L"\uF1AA", CategoryGroupType::Converter, MyVirtualKey::None, POSITIVE_ONLY },
NavCategoryInitializer { ViewMode::Length, LENGTH_ID, L"Length", L"CategoryName_Length", L"\uECC6", CategoryGroupType::Converter, MyVirtualKey::None, POSITIVE_ONLY },
NavCategoryInitializer { ViewMode::Weight, WEIGHT_ID, L"Weight and Mass", L"CategoryName_Weight", L"\uF4C1", CategoryGroupType::Converter, MyVirtualKey::None, POSITIVE_ONLY },
NavCategoryInitializer { ViewMode::Temperature, TEMPERATURE_ID, L"Temperature", L"CategoryName_Temperature", L"\uE7A3", CategoryGroupType::Converter, MyVirtualKey::None, SUPPORTS_NEGATIVE },
NavCategoryInitializer { ViewMode::Energy, ENERGY_ID, L"Energy", L"CategoryName_Energy", L"\uECAD", CategoryGroupType::Converter, MyVirtualKey::None, POSITIVE_ONLY },
NavCategoryInitializer { ViewMode::Area, AREA_ID, L"Area", L"CategoryName_Area", L"\uE809", CategoryGroupType::Converter, MyVirtualKey::None, POSITIVE_ONLY },
NavCategoryInitializer { ViewMode::Speed, SPEED_ID, L"Speed", L"CategoryName_Speed", L"\uEADA", CategoryGroupType::Converter, MyVirtualKey::None, POSITIVE_ONLY },
NavCategoryInitializer { ViewMode::Time, TIME_ID, L"Time", L"CategoryName_Time", L"\uE917", CategoryGroupType::Converter, MyVirtualKey::None, POSITIVE_ONLY },
NavCategoryInitializer { ViewMode::Power, POWER_ID, L"Power", L"CategoryName_Power", L"\uE945", CategoryGroupType::Converter, MyVirtualKey::None, POSITIVE_ONLY },
NavCategoryInitializer { ViewMode::Data, DATA_ID, L"Data", L"CategoryName_Data", L"\uF20F", CategoryGroupType::Converter, MyVirtualKey::None, POSITIVE_ONLY },
NavCategoryInitializer { ViewMode::Pressure, PRESSURE_ID, L"Pressure", L"CategoryName_Pressure", L"\uEC4A", CategoryGroupType::Converter, MyVirtualKey::None, POSITIVE_ONLY },
NavCategoryInitializer { ViewMode::Angle, ANGLE_ID, L"Angle", L"CategoryName_Angle", L"\uF515", CategoryGroupType::Converter, MyVirtualKey::None, POSITIVE_ONLY }
NavCategoryInitializer{ ViewMode::Standard, STANDARD_ID, L"Standard", L"StandardMode", L"\uE8EF", CategoryGroupType::Calculator, MyVirtualKey::Number1,
SUPPORTS_ALL },
NavCategoryInitializer{ ViewMode::Scientific, SCIENTIFIC_ID, L"Scientific", L"ScientificMode", L"\uF196", CategoryGroupType::Calculator,
MyVirtualKey::Number2, SUPPORTS_ALL },
NavCategoryInitializer{ ViewMode::Programmer, PROGRAMMER_ID, L"Programmer", L"ProgrammerMode", L"\uECCE", CategoryGroupType::Calculator,
MyVirtualKey::Number3, SUPPORTS_ALL },
NavCategoryInitializer{ ViewMode::Date, DATE_ID, L"Date", L"DateCalculationMode", L"\uE787", CategoryGroupType::Calculator, MyVirtualKey::Number4,
SUPPORTS_ALL },
NavCategoryInitializer{ ViewMode::Currency, CURRENCY_ID, L"Currency", L"CategoryName_Currency", L"\uEB0D", CategoryGroupType::Converter, MyVirtualKey::None,
POSITIVE_ONLY },
NavCategoryInitializer{ ViewMode::Volume, VOLUME_ID, L"Volume", L"CategoryName_Volume", L"\uF1AA", CategoryGroupType::Converter, MyVirtualKey::None,
POSITIVE_ONLY },
NavCategoryInitializer{ ViewMode::Length, LENGTH_ID, L"Length", L"CategoryName_Length", L"\uECC6", CategoryGroupType::Converter, MyVirtualKey::None,
POSITIVE_ONLY },
NavCategoryInitializer{ ViewMode::Weight, WEIGHT_ID, L"Weight and Mass", L"CategoryName_Weight", L"\uF4C1", CategoryGroupType::Converter,
MyVirtualKey::None, POSITIVE_ONLY },
NavCategoryInitializer{ ViewMode::Temperature, TEMPERATURE_ID, L"Temperature", L"CategoryName_Temperature", L"\uE7A3", CategoryGroupType::Converter,
MyVirtualKey::None, SUPPORTS_NEGATIVE },
NavCategoryInitializer{ ViewMode::Energy, ENERGY_ID, L"Energy", L"CategoryName_Energy", L"\uECAD", CategoryGroupType::Converter, MyVirtualKey::None,
POSITIVE_ONLY },
NavCategoryInitializer{ ViewMode::Area, AREA_ID, L"Area", L"CategoryName_Area", L"\uE809", CategoryGroupType::Converter, MyVirtualKey::None,
POSITIVE_ONLY },
NavCategoryInitializer{ ViewMode::Speed, SPEED_ID, L"Speed", L"CategoryName_Speed", L"\uEADA", CategoryGroupType::Converter, MyVirtualKey::None,
POSITIVE_ONLY },
NavCategoryInitializer{ ViewMode::Time, TIME_ID, L"Time", L"CategoryName_Time", L"\uE917", CategoryGroupType::Converter, MyVirtualKey::None,
POSITIVE_ONLY },
NavCategoryInitializer{ ViewMode::Power, POWER_ID, L"Power", L"CategoryName_Power", L"\uE945", CategoryGroupType::Converter, MyVirtualKey::None,
POSITIVE_ONLY },
NavCategoryInitializer{ ViewMode::Data, DATA_ID, L"Data", L"CategoryName_Data", L"\uF20F", CategoryGroupType::Converter, MyVirtualKey::None,
POSITIVE_ONLY },
NavCategoryInitializer{ ViewMode::Pressure, PRESSURE_ID, L"Pressure", L"CategoryName_Pressure", L"\uEC4A", CategoryGroupType::Converter, MyVirtualKey::None,
POSITIVE_ONLY },
NavCategoryInitializer{ ViewMode::Angle, ANGLE_ID, L"Angle", L"CategoryName_Angle", L"\uF515", CategoryGroupType::Converter, MyVirtualKey::None,
POSITIVE_ONLY }
};
// This function should only be used when storing the mode to app data.
int NavCategory::Serialize(ViewMode mode)
{
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest),
[mode](const NavCategoryInitializer& initializer)
{
return initializer.viewMode == mode;
});
auto iter =
find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode](const NavCategoryInitializer& initializer) { return initializer.viewMode == mode; });
return (iter != s_categoryManifest.end())
? iter->serializationId
: -1;
return (iter != s_categoryManifest.end()) ? iter->serializationId : -1;
}
// This function should only be used when restoring the mode from app data.
ViewMode NavCategory::Deserialize(Platform::Object^ obj)
ViewMode NavCategory::Deserialize(Platform::Object ^ obj)
{
// If we cast directly to ViewMode we will fail
// because we technically store an int.
// Need to cast to int, then ViewMode.
auto boxed = dynamic_cast<Box<int>^>(obj);
auto boxed = dynamic_cast<Box<int> ^>(obj);
if (boxed != nullptr)
{
int serializationId = boxed->Value;
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest),
[serializationId](const NavCategoryInitializer& initializer)
{
return initializer.serializationId == serializationId;
});
[serializationId](const NavCategoryInitializer& initializer) { return initializer.serializationId == serializationId; });
if (iter != s_categoryManifest.end())
{
@@ -110,11 +119,8 @@ ViewMode NavCategory::Deserialize(Platform::Object^ obj)
bool NavCategory::IsValidViewMode(ViewMode mode)
{
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest),
[mode](const NavCategoryInitializer& initializer)
{
return initializer.viewMode == mode;
});
auto iter =
find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode](const NavCategoryInitializer& initializer) { return initializer.viewMode == mode; });
return iter != s_categoryManifest.end();
}
@@ -139,64 +145,41 @@ bool NavCategory::IsConverterViewMode(ViewMode mode)
bool NavCategory::IsModeInCategoryGroup(ViewMode mode, CategoryGroupType type)
{
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest),
[mode, type](const NavCategoryInitializer& initializer)
{
return initializer.viewMode == mode && initializer.groupType == type;
});
[mode, type](const NavCategoryInitializer& initializer) { return initializer.viewMode == mode && initializer.groupType == type; });
return iter != s_categoryManifest.end();
}
String^ NavCategory::GetFriendlyName(ViewMode mode)
String ^ NavCategory::GetFriendlyName(ViewMode mode)
{
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest),
[mode](const NavCategoryInitializer& initializer)
{
return initializer.viewMode == mode;
});
auto iter =
find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode](const NavCategoryInitializer& initializer) { return initializer.viewMode == mode; });
return (iter != s_categoryManifest.end())
? StringReference(iter->friendlyName)
: L"None";
return (iter != s_categoryManifest.end()) ? StringReference(iter->friendlyName) : L"None";
}
ViewMode NavCategory::GetViewModeForFriendlyName(String^ name)
ViewMode NavCategory::GetViewModeForFriendlyName(String ^ name)
{
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest),
[name](const NavCategoryInitializer& initializer)
{
return wcscmp(initializer.friendlyName, name->Data()) == 0;
});
[name](const NavCategoryInitializer& initializer) { return wcscmp(initializer.friendlyName, name->Data()) == 0; });
return (iter != s_categoryManifest.end())
? iter->viewMode
: ViewMode::None;
return (iter != s_categoryManifest.end()) ? iter->viewMode : ViewMode::None;
}
String^ NavCategory::GetNameResourceKey(ViewMode mode)
String ^ NavCategory::GetNameResourceKey(ViewMode mode)
{
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest),
[mode](const NavCategoryInitializer& initializer)
{
return initializer.viewMode == mode;
});
auto iter =
find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode](const NavCategoryInitializer& initializer) { return initializer.viewMode == mode; });
return (iter != s_categoryManifest.end())
? StringReference(iter->nameResourceKey) + "Text"
: nullptr;
return (iter != s_categoryManifest.end()) ? StringReference(iter->nameResourceKey) + "Text" : nullptr;
}
CategoryGroupType NavCategory::GetGroupType(ViewMode mode)
{
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest),
[mode](const NavCategoryInitializer& initializer)
{
return initializer.viewMode == mode;
});
auto iter =
find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode](const NavCategoryInitializer& initializer) { return initializer.viewMode == mode; });
return (iter != s_categoryManifest.end())
? iter->groupType
: CategoryGroupType::None;
return (iter != s_categoryManifest.end()) ? iter->groupType : CategoryGroupType::None;
}
// GetIndex is 0-based, GetPosition is 1-based
@@ -210,9 +193,7 @@ int NavCategory::GetFlatIndex(ViewMode mode)
{
int index = -1;
CategoryGroupType type = CategoryGroupType::None;
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest),
[mode, &type, &index](const NavCategoryInitializer& initializer)
{
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode, &type, &index](const NavCategoryInitializer& initializer) {
index++;
if (initializer.groupType != type)
{
@@ -223,18 +204,14 @@ int NavCategory::GetFlatIndex(ViewMode mode)
return initializer.viewMode == mode;
});
return (iter != s_categoryManifest.end())
? index
: -1;
return (iter != s_categoryManifest.end()) ? index : -1;
}
// GetIndex is 0-based, GetPosition is 1-based
int NavCategory::GetIndexInGroup(ViewMode mode, CategoryGroupType type)
{
int index = -1;
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest),
[mode, type, &index](const NavCategoryInitializer& initializer)
{
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode, type, &index](const NavCategoryInitializer& initializer) {
if (initializer.groupType == type)
{
index++;
@@ -244,38 +221,27 @@ int NavCategory::GetIndexInGroup(ViewMode mode, CategoryGroupType type)
return false;
});
return (iter != s_categoryManifest.end())
? index
: -1;
return (iter != s_categoryManifest.end()) ? index : -1;
}
// GetIndex is 0-based, GetPosition is 1-based
int NavCategory::GetPosition(ViewMode mode)
{
int position = 0;
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest),
[mode, &position](const NavCategoryInitializer& initializer)
{
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode, &position](const NavCategoryInitializer& initializer) {
position++;
return initializer.viewMode == mode;
});
return (iter != s_categoryManifest.end())
? position
: -1;
return (iter != s_categoryManifest.end()) ? position : -1;
}
ViewMode NavCategory::GetViewModeForVirtualKey(MyVirtualKey virtualKey)
{
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest),
[virtualKey](const NavCategoryInitializer& initializer)
{
return initializer.virtualKey == virtualKey;
});
[virtualKey](const NavCategoryInitializer& initializer) { return initializer.virtualKey == virtualKey; });
return (iter != s_categoryManifest.end())
? iter->viewMode
: ViewMode::None;
return (iter != s_categoryManifest.end()) ? iter->viewMode : ViewMode::None;
}
vector<MyVirtualKey> NavCategory::GetCategoryAcceleratorKeys()
@@ -292,63 +258,54 @@ vector<MyVirtualKey> NavCategory::GetCategoryAcceleratorKeys()
return accelerators;
}
NavCategoryGroup::NavCategoryGroup(const NavCategoryGroupInitializer& groupInitializer) :
m_Categories(ref new Vector<NavCategory^>())
NavCategoryGroup::NavCategoryGroup(const NavCategoryGroupInitializer& groupInitializer) : m_Categories(ref new Vector<NavCategory ^>())
{
m_GroupType = groupInitializer.type;
auto resProvider = AppResourceProvider::GetInstance();
String^ headerResourceKey = StringReference(groupInitializer.headerResourceKey);
String^ modeResourceKey = StringReference(groupInitializer.modeResourceKey);
String^ automationResourceKey = StringReference(groupInitializer.automationResourceKey);
String ^ headerResourceKey = StringReference(groupInitializer.headerResourceKey);
String ^ modeResourceKey = StringReference(groupInitializer.modeResourceKey);
String ^ automationResourceKey = StringReference(groupInitializer.automationResourceKey);
m_Name = resProvider.GetResourceString(headerResourceKey);
String^ groupMode = resProvider.GetResourceString(modeResourceKey);
String^ automationName = resProvider.GetResourceString(automationResourceKey);
String ^ groupMode = resProvider.GetResourceString(modeResourceKey);
String ^ automationName = resProvider.GetResourceString(automationResourceKey);
String^ navCategoryHeaderAutomationNameFormat = resProvider.GetResourceString(L"NavCategoryHeader_AutomationNameFormat");
m_AutomationName = ref new String(LocalizationStringUtil::GetLocalizedString(
navCategoryHeaderAutomationNameFormat->Data(),
automationName->Data()).c_str());
String ^ navCategoryHeaderAutomationNameFormat = resProvider.GetResourceString(L"NavCategoryHeader_AutomationNameFormat");
m_AutomationName =
ref new String(LocalizationStringUtil::GetLocalizedString(navCategoryHeaderAutomationNameFormat->Data(), automationName->Data()).c_str());
String^ navCategoryItemAutomationNameFormat = resProvider.GetResourceString(L"NavCategoryItem_AutomationNameFormat");
String ^ navCategoryItemAutomationNameFormat = resProvider.GetResourceString(L"NavCategoryItem_AutomationNameFormat");
for (const NavCategoryInitializer& categoryInitializer : s_categoryManifest)
{
if (categoryInitializer.groupType == groupInitializer.type)
{
String^ nameResourceKey = StringReference(categoryInitializer.nameResourceKey);
String^ categoryName = resProvider.GetResourceString(nameResourceKey + "Text");
String^ categoryAutomationName = ref new String(LocalizationStringUtil::GetLocalizedString(
navCategoryItemAutomationNameFormat->Data(),
categoryName->Data(),
m_Name->Data()).c_str());
String ^ nameResourceKey = StringReference(categoryInitializer.nameResourceKey);
String ^ categoryName = resProvider.GetResourceString(nameResourceKey + "Text");
String ^ categoryAutomationName = ref new String(
LocalizationStringUtil::GetLocalizedString(navCategoryItemAutomationNameFormat->Data(), categoryName->Data(), m_Name->Data()).c_str());
m_Categories->Append(ref new NavCategory(
categoryName,
categoryAutomationName,
StringReference(categoryInitializer.glyph),
resProvider.GetResourceString(nameResourceKey + "AccessKey"),
groupMode,
categoryInitializer.viewMode,
categoryInitializer.supportsNegative));
m_Categories->Append(ref new NavCategory(categoryName, categoryAutomationName, StringReference(categoryInitializer.glyph),
resProvider.GetResourceString(nameResourceKey + "AccessKey"), groupMode, categoryInitializer.viewMode,
categoryInitializer.supportsNegative));
}
}
}
IObservableVector<NavCategoryGroup^>^ NavCategoryGroup::CreateMenuOptions()
IObservableVector<NavCategoryGroup ^> ^ NavCategoryGroup::CreateMenuOptions()
{
auto menuOptions = ref new Vector<NavCategoryGroup^>();
auto menuOptions = ref new Vector<NavCategoryGroup ^>();
menuOptions->Append(CreateCalculatorCategory());
menuOptions->Append(CreateConverterCategory());
return menuOptions;
}
NavCategoryGroup^ NavCategoryGroup::CreateCalculatorCategory()
NavCategoryGroup ^ NavCategoryGroup::CreateCalculatorCategory()
{
return ref new NavCategoryGroup(s_categoryGroupManifest.at(0));
}
NavCategoryGroup^ NavCategoryGroup::CreateConverterCategory()
NavCategoryGroup ^ NavCategoryGroup::CreateConverterCategory()
{
return ref new NavCategoryGroup(s_categoryGroupManifest.at(1));
}
@@ -357,23 +314,15 @@ vector<NavCategoryInitializer> NavCategoryGroup::GetInitializerCategoryGroup(Cat
{
vector<NavCategoryInitializer> initializers{};
copy_if(begin(s_categoryManifest), end(s_categoryManifest), back_inserter(initializers),
[groupType](const NavCategoryInitializer& initializer)
{
return initializer.groupType == groupType;
});
[groupType](const NavCategoryInitializer& initializer) { return initializer.groupType == groupType; });
return initializers;
}
String^ NavCategoryGroup::GetHeaderResourceKey(CategoryGroupType type)
String ^ NavCategoryGroup::GetHeaderResourceKey(CategoryGroupType type)
{
auto iter = find_if(begin(s_categoryGroupManifest), end(s_categoryGroupManifest),
[type](const NavCategoryGroupInitializer& initializer)
{
return initializer.type == type;
});
[type](const NavCategoryGroupInitializer& initializer) { return initializer.type == type; });
return (iter != s_categoryGroupManifest.end())
? StringReference(iter->headerResourceKey)
: nullptr;
return (iter != s_categoryGroupManifest.end()) ? StringReference(iter->headerResourceKey) : nullptr;
}

View File

@@ -24,7 +24,8 @@ namespace CalculatorApp
// Don't change the order of these enums
// and definitely don't use int arithmetic
// to change modes.
public enum class ViewMode
public
enum class ViewMode
{
None = -1,
Standard = 0,
@@ -46,81 +47,74 @@ namespace CalculatorApp
Currency = 16
};
public enum class CategoryGroupType
public
enum class CategoryGroupType
{
None = -1,
Calculator = 0,
Converter = 1
};
private struct NavCategoryInitializer
private
struct NavCategoryInitializer
{
constexpr NavCategoryInitializer(
ViewMode mode,
int id,
wchar_t const * name,
wchar_t const * nameKey,
wchar_t const * glyph,
CategoryGroupType group,
MyVirtualKey vKey,
bool categorySupportsNegative)
:
viewMode(mode),
serializationId(id),
friendlyName(name),
nameResourceKey(nameKey),
glyph(glyph),
groupType(group),
virtualKey(vKey),
supportsNegative(categorySupportsNegative)
{}
constexpr NavCategoryInitializer(ViewMode mode, int id, wchar_t const* name, wchar_t const* nameKey, wchar_t const* glyph, CategoryGroupType group,
MyVirtualKey vKey, bool categorySupportsNegative)
: viewMode(mode)
, serializationId(id)
, friendlyName(name)
, nameResourceKey(nameKey)
, glyph(glyph)
, groupType(group)
, virtualKey(vKey)
, supportsNegative(categorySupportsNegative)
{
}
const ViewMode viewMode;
const int serializationId;
const wchar_t * const friendlyName;
const wchar_t * const nameResourceKey;
const wchar_t * const glyph;
const wchar_t* const friendlyName;
const wchar_t* const nameResourceKey;
const wchar_t* const glyph;
const CategoryGroupType groupType;
const MyVirtualKey virtualKey;
const bool supportsNegative;
};
private struct NavCategoryGroupInitializer
private
struct NavCategoryGroupInitializer
{
constexpr NavCategoryGroupInitializer(CategoryGroupType t, wchar_t const * h, wchar_t const * n, wchar_t const * a) :
type(t), headerResourceKey(h), modeResourceKey(n), automationResourceKey(a)
{}
constexpr NavCategoryGroupInitializer(CategoryGroupType t, wchar_t const* h, wchar_t const* n, wchar_t const* a)
: type(t), headerResourceKey(h), modeResourceKey(n), automationResourceKey(a)
{
}
const CategoryGroupType type;
const wchar_t *headerResourceKey;
const wchar_t *modeResourceKey;
const wchar_t *automationResourceKey;
const wchar_t* headerResourceKey;
const wchar_t* modeResourceKey;
const wchar_t* automationResourceKey;
};
[Windows::UI::Xaml::Data::Bindable]
public ref class NavCategory sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
[Windows::UI::Xaml::Data::Bindable] public ref class NavCategory sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
public:
OBSERVABLE_OBJECT();
property Platform::String^ Name
{
Platform::String^ get() { return m_name; }
}
property Platform::String
^ Name { Platform::String ^ get() { return m_name; } }
property Platform::String^ AutomationName
{
Platform::String^ get() { return m_automationName; }
}
property Platform::String
^ AutomationName { Platform::String ^ get() { return m_automationName; } }
property Platform::String^ Glyph
{
Platform::String^ get() { return m_glyph; }
}
property Platform::String
^ Glyph { Platform::String ^ get() { return m_glyph; } }
property int Position
property int Position
{
int get() { return m_position; }
int get()
{
return m_position;
}
}
property ViewMode Mode
@@ -131,24 +125,13 @@ namespace CalculatorApp
}
}
property Platform::String^ AutomationId
{
Platform::String^ get()
{
return m_viewMode.ToString();
}
}
property Platform::String
^ AutomationId { Platform::String ^ get() { return m_viewMode.ToString(); } }
property Platform::String^ AccessKey
{
Platform::String^ get()
{
return m_accessKey;
}
}
property Platform::String
^ AccessKey { Platform::String ^ get() { return m_accessKey; } }
property bool SupportsNegative
property bool SupportsNegative
{
bool get()
{
@@ -158,16 +141,16 @@ namespace CalculatorApp
// For saving/restoring last mode used.
static int Serialize(ViewMode mode);
static ViewMode Deserialize(Platform::Object^ obj);
static ViewMode GetViewModeForFriendlyName(Platform::String^ name);
static ViewMode Deserialize(Platform::Object ^ obj);
static ViewMode GetViewModeForFriendlyName(Platform::String ^ name);
static bool IsValidViewMode(ViewMode mode);
static bool IsCalculatorViewMode(ViewMode mode);
static bool IsDateCalculatorViewMode(ViewMode mode);
static bool IsConverterViewMode(ViewMode mode);
static Platform::String^ GetFriendlyName(ViewMode mode);
static Platform::String^ GetNameResourceKey(ViewMode mode);
static Platform::String ^ GetFriendlyName(ViewMode mode);
static Platform::String ^ GetNameResourceKey(ViewMode mode);
static CategoryGroupType GetGroupType(ViewMode mode);
// GetIndex is 0-based, GetPosition is 1-based
@@ -178,15 +161,15 @@ namespace CalculatorApp
static ViewMode GetViewModeForVirtualKey(MyVirtualKey virtualKey);
internal:
NavCategory(Platform::String^ name, Platform::String^ automationName, Platform::String^ glyph, Platform::String^ accessKey, Platform::String^ mode, ViewMode viewMode, bool supportsNegative) :
m_name(name),
m_automationName(automationName),
m_glyph(glyph),
m_accessKey(accessKey),
m_mode(mode),
m_viewMode(viewMode),
m_supportsNegative(supportsNegative)
internal : NavCategory(Platform::String ^ name, Platform::String ^ automationName, Platform::String ^ glyph, Platform::String ^ accessKey,
Platform::String ^ mode, ViewMode viewMode, bool supportsNegative)
: m_name(name)
, m_automationName(automationName)
, m_glyph(glyph)
, m_accessKey(accessKey)
, m_mode(mode)
, m_viewMode(viewMode)
, m_supportsNegative(supportsNegative)
{
m_position = NavCategory::GetPosition(m_viewMode);
}
@@ -197,33 +180,30 @@ namespace CalculatorApp
static bool IsModeInCategoryGroup(ViewMode mode, CategoryGroupType groupType);
ViewMode m_viewMode;
Platform::String^ m_name;
Platform::String^ m_automationName;
Platform::String^ m_glyph;
Platform::String^ m_accessKey;
Platform::String^ m_mode;
Platform::String ^ m_name;
Platform::String ^ m_automationName;
Platform::String ^ m_glyph;
Platform::String ^ m_accessKey;
Platform::String ^ m_mode;
int m_position;
bool m_supportsNegative;
};
[Windows::UI::Xaml::Data::Bindable]
public ref class NavCategoryGroup sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
[Windows::UI::Xaml::Data::Bindable] public ref class NavCategoryGroup sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
public:
OBSERVABLE_OBJECT();
OBSERVABLE_PROPERTY_R(Platform::String^, Name);
OBSERVABLE_PROPERTY_R(Platform::String^, AutomationName);
OBSERVABLE_PROPERTY_R(Platform::String ^, Name);
OBSERVABLE_PROPERTY_R(Platform::String ^, AutomationName);
OBSERVABLE_PROPERTY_R(CategoryGroupType, GroupType);
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<NavCategory^>^, Categories);
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<NavCategory ^> ^, Categories);
static Windows::Foundation::Collections::IObservableVector<NavCategoryGroup^>^ CreateMenuOptions();
static Windows::Foundation::Collections::IObservableVector<NavCategoryGroup ^> ^ CreateMenuOptions();
static Platform::String^ GetHeaderResourceKey(CategoryGroupType type);
static Platform::String ^ GetHeaderResourceKey(CategoryGroupType type);
internal:
static NavCategoryGroup^ CreateCalculatorCategory();
static NavCategoryGroup^ CreateConverterCategory();
internal : static NavCategoryGroup ^ CreateCalculatorCategory();
static NavCategoryGroup ^ CreateConverterCategory();
private:
NavCategoryGroup(const NavCategoryGroupInitializer& groupInitializer);

View File

@@ -10,9 +10,8 @@ using namespace Windows::Networking::Connectivity;
NetworkManager::NetworkManager()
{
m_NetworkStatusChangedToken =
NetworkInformation::NetworkStatusChanged += ref new NetworkStatusChangedEventHandler(
this, &NetworkManager::OnNetworkStatusChange, CallbackContext::Same);
m_NetworkStatusChangedToken = NetworkInformation::NetworkStatusChanged +=
ref new NetworkStatusChangedEventHandler(this, &NetworkManager::OnNetworkStatusChange, CallbackContext::Same);
}
NetworkManager::~NetworkManager()
@@ -23,14 +22,13 @@ NetworkManager::~NetworkManager()
NetworkAccessBehavior NetworkManager::GetNetworkAccessBehavior()
{
NetworkAccessBehavior behavior = NetworkAccessBehavior::Offline;
ConnectionProfile^ connectionProfile = NetworkInformation::GetInternetConnectionProfile();
ConnectionProfile ^ connectionProfile = NetworkInformation::GetInternetConnectionProfile();
if (connectionProfile != nullptr)
{
NetworkConnectivityLevel connectivityLevel = connectionProfile->GetNetworkConnectivityLevel();
if (connectivityLevel == NetworkConnectivityLevel::InternetAccess
|| connectivityLevel == NetworkConnectivityLevel::ConstrainedInternetAccess)
if (connectivityLevel == NetworkConnectivityLevel::InternetAccess || connectivityLevel == NetworkConnectivityLevel::ConstrainedInternetAccess)
{
ConnectionCost^ connectionCost = connectionProfile->GetConnectionCost();
ConnectionCost ^ connectionCost = connectionProfile->GetConnectionCost();
behavior = ConvertCostInfoToBehavior(connectionCost);
}
}
@@ -38,16 +36,15 @@ NetworkAccessBehavior NetworkManager::GetNetworkAccessBehavior()
return behavior;
}
void NetworkManager::OnNetworkStatusChange(_In_ Object^ /*sender*/)
void NetworkManager::OnNetworkStatusChange(_In_ Object ^ /*sender*/)
{
NetworkBehaviorChanged(GetNetworkAccessBehavior());
}
// See app behavior guidelines at https://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj835821(v=win.10).aspx
NetworkAccessBehavior NetworkManager::ConvertCostInfoToBehavior(_In_ ConnectionCost^ connectionCost)
NetworkAccessBehavior NetworkManager::ConvertCostInfoToBehavior(_In_ ConnectionCost ^ connectionCost)
{
if (connectionCost->Roaming || connectionCost->OverDataLimit
|| connectionCost->NetworkCostType == NetworkCostType::Variable
if (connectionCost->Roaming || connectionCost->OverDataLimit || connectionCost->NetworkCostType == NetworkCostType::Variable
|| connectionCost->NetworkCostType == NetworkCostType::Fixed)
{
return NetworkAccessBehavior::OptIn;

View File

@@ -5,29 +5,32 @@
namespace CalculatorApp
{
public enum class NetworkAccessBehavior
public
enum class NetworkAccessBehavior
{
Normal = 0,
OptIn = 1,
Offline = 2
};
public delegate void NetworkBehaviorChangedHandler(NetworkAccessBehavior behavior);
public
delegate void NetworkBehaviorChangedHandler(NetworkAccessBehavior behavior);
public ref class NetworkManager sealed
public
ref class NetworkManager sealed
{
public:
NetworkManager();
static NetworkAccessBehavior GetNetworkAccessBehavior();
event NetworkBehaviorChangedHandler^ NetworkBehaviorChanged;
event NetworkBehaviorChangedHandler ^ NetworkBehaviorChanged;
private:
~NetworkManager();
void OnNetworkStatusChange(_In_ Platform::Object^ sender);
static NetworkAccessBehavior ConvertCostInfoToBehavior(_In_ Windows::Networking::Connectivity::ConnectionCost^ connectionCost);
void OnNetworkStatusChange(_In_ Platform::Object ^ sender);
static NetworkAccessBehavior ConvertCostInfoToBehavior(_In_ Windows::Networking::Connectivity::ConnectionCost ^ connectionCost);
private:
Windows::Foundation::EventRegistrationToken m_NetworkStatusChangedToken;

View File

@@ -11,30 +11,19 @@ namespace CalculatorApp
class TraceActivity
{
public:
TraceActivity() :
m_channel(nullptr),
m_activity(nullptr),
m_fields(nullptr)
{ }
TraceActivity() : m_channel(nullptr), m_activity(nullptr), m_fields(nullptr)
{
}
TraceActivity(
winrt::Windows::Foundation::Diagnostics::LoggingChannel channel,
std::wstring_view activityName,
winrt::Windows::Foundation::Diagnostics::LoggingFields fields) :
m_channel(channel),
m_activityName(activityName),
m_fields(fields),
m_activity(nullptr)
TraceActivity(winrt::Windows::Foundation::Diagnostics::LoggingChannel channel, std::wstring_view activityName,
winrt::Windows::Foundation::Diagnostics::LoggingFields fields)
: m_channel(channel), m_activityName(activityName), m_fields(fields), m_activity(nullptr)
{
// Write the activity's START event. Note that you must not specify keyword
// or level for START and STOP events because they always use the activity's
// keyword and level.
m_activity = m_channel.StartActivity(
m_activityName,
m_fields,
winrt::Windows::Foundation::Diagnostics::LoggingLevel::Verbose,
winrt::Windows::Foundation::Diagnostics::LoggingOptions(WINEVENT_KEYWORD_RESPONSE_TIME)
);
m_activity = m_channel.StartActivity(m_activityName, m_fields, winrt::Windows::Foundation::Diagnostics::LoggingLevel::Verbose,
winrt::Windows::Foundation::Diagnostics::LoggingOptions(WINEVENT_KEYWORD_RESPONSE_TIME));
}
~TraceActivity()

View File

@@ -21,74 +21,72 @@ namespace CalculatorApp
{
static multimap<int, vector<wstring>> s_memoryMap;
static constexpr array<const wchar_t * const, 9> s_programmerType{
L"N/A", L"QwordType", L"DwordType",
L"WordType", L"ByteType", L"HexBase",
L"DecBase", L"OctBase", L"BinBase" };
static constexpr array<const wchar_t* const, 9> s_programmerType{ L"N/A", L"QwordType", L"DwordType", L"WordType", L"ByteType",
L"HexBase", L"DecBase", L"OctBase", L"BinBase" };
static reader_writer_lock s_traceLoggerLock;
// Telemetry events. Uploaded to asimov.
constexpr auto EVENT_NAME_DEBUG = L"Debug";
constexpr auto EVENT_NAME_ERROR = L"ErrorMessage";
constexpr auto EVENT_NAME_APP_PRELAUNCHED_BY_SYSTEM = L"AppPrelaunchedBySystem";
constexpr auto EVENT_NAME_PRELAUNCHED_APP_ACTIVATED_BY_USER = L"PrelaunchedAppActivatedByUser";
constexpr auto EVENT_NAME_APP_LAUNCH_BEGIN = L"AppLaunchBegin";
constexpr auto EVENT_NAME_APP_LAUNCH_END = L"AppLaunchEnd";
constexpr auto EVENT_NAME_APP_RESUME_END = L"AppResumeEnd";
constexpr auto EVENT_NAME_PREVIOUS_STATE_WINDOW_ON_CREATION = L"PreviousStateOnWindowCreation";
constexpr auto EVENT_NAME_SIZE_ON_SUSPENSION = L"CalculatorSizeOnSuspension";
constexpr auto EVENT_NAME_CALCULATOR_VIEWED_IN_SESSION = L"CalculatorViewedInSession";
constexpr auto EVENT_NAME_DATE_CALCULATOR_VIEWED_IN_SESSION = L"DateCalculatorViewedInSession";
constexpr auto EVENT_NAME_CONVERTER_VIEWED_IN_SESSION = L"ConverterViewedInSession";
constexpr auto EVENT_NAME_MODE_CHANGE_BEGIN = L"ModeChangeBegin";
constexpr auto EVENT_NAME_MODE_CHANGE_END = L"ModeChangeEnd";
constexpr auto EVENT_NAME_HISTORY_BODY_OPENED = L"HistoryBodyOpened";
constexpr auto EVENT_NAME_HISTORY_ITEM_LOAD_BEGIN = L"HistoryItemLoadBegin";
constexpr auto EVENT_NAME_HISTORY_ITEM_LOAD_END = L"HistoryItemLoadEnd";
constexpr auto EVENT_NAME_HISTORY_FLYOUT_OPEN_BEGIN = L"HistoryFlyoutOpenBegin";
constexpr auto EVENT_NAME_HISTORY_FLYOUT_OPEN_END = L"HistoryFlyoutOpenEnd";
constexpr auto EVENT_NAME_NEW_WINDOW_CREATION_BEGIN = L"NewWindowCreationBegin";
constexpr auto EVENT_NAME_NEW_WINDOW_CREATION_END = L"NewWindowCreationEnd";
constexpr auto EVENT_NAME_HISTORY_CLEAR = L"HistoryClearBegin";
constexpr auto EVENT_NAME_MULTIPLE_MEMORY_USED = L"MultipleMemoryUsed";
constexpr auto EVENT_NAME_SINGLE_MEMORY_USED = L"SingleMemoryUsed";
constexpr auto EVENT_NAME_SHARED_MEMORY_USED = L"SharedMemoryUsed";
constexpr auto EVENT_NAME_MEMORY_BODY_OPENED = L"MemoryBodyOpened";
constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_BEGIN = L"MemoryFlyoutOpenBegin";
constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_END = L"MemoryFlyoutOpenEnd";
constexpr auto EVENT_NAME_MEMORY_CLEAR_ALL = L"MemoryClearAll";
constexpr auto EVENT_NAME_INVALID_PASTED_INPUT_OCCURRED = L"InvalidPastedInputOccurred";
constexpr auto EVENT_NAME_VALID_INPUT_PASTED = L"ValidInputPasted";
constexpr auto EVENT_NAME_BITFLIP_PANE_CLICKED = L"BitFlipPaneClicked";
constexpr auto EVENT_NAME_BITFLIP_BUTTONS_USED = L"BitFlipToggleButtonUsed";
constexpr auto EVENT_NAME_ANGLE_BUTTONS_USED = L"AngleButtonUsedInSession";
constexpr auto EVENT_NAME_HYP_BUTTON_USED = L"HypButtonUsedInSession";
constexpr auto EVENT_NAME_FUNCTION_USAGE = L"FunctionUsageInSession";
constexpr auto EVENT_NAME_BITLENGTH_BUTTON_USED = L"BitLengthButtonUsed";
constexpr auto EVENT_NAME_RADIX_BUTTON_USED = L"RadixButtonUsed";
constexpr auto EVENT_NAME_MAX_WINDOW_COUNT = L"MaxWindowCountInSession";
constexpr auto EVENT_NAME_WINDOW_LAUNCHED_PROTOCOL = L"WindowActivatedThroughProtocol";
constexpr auto EVENT_NAME_WINDOW_LAUNCHED_TILESEARCH = L"WindowLaunchedThroughTile";
constexpr auto EVENT_NAME_DATE_DIFFERENCE_USED = L"DateDifferenceModeUsed";
constexpr auto EVENT_NAME_DATE_ADD_SUBTRACT_USED = L"DateAddSubtractModeUsed";
constexpr auto EVENT_NAME_DATE_DIFFERENCE_FOUND = L"DateDifferenceFound";
constexpr auto EVENT_NAME_HIDE_IF_SHOWN = L"HideIfShown";
constexpr auto EVENT_NAME_ABOUT_FLYOUT_OPENED = L"AboutFlyoutOpened";
constexpr auto EVENT_NAME_NAV_BAR_OPENED = L"NavBarOpened";
constexpr auto EVENT_NAME_CORE_WINDOW_WAS_NULL = L"CoreWindowWasNull";
constexpr auto EVENT_NAME_DEBUG = L"Debug";
constexpr auto EVENT_NAME_ERROR = L"ErrorMessage";
constexpr auto EVENT_NAME_APP_PRELAUNCHED_BY_SYSTEM = L"AppPrelaunchedBySystem";
constexpr auto EVENT_NAME_PRELAUNCHED_APP_ACTIVATED_BY_USER = L"PrelaunchedAppActivatedByUser";
constexpr auto EVENT_NAME_APP_LAUNCH_BEGIN = L"AppLaunchBegin";
constexpr auto EVENT_NAME_APP_LAUNCH_END = L"AppLaunchEnd";
constexpr auto EVENT_NAME_APP_RESUME_END = L"AppResumeEnd";
constexpr auto EVENT_NAME_PREVIOUS_STATE_WINDOW_ON_CREATION = L"PreviousStateOnWindowCreation";
constexpr auto EVENT_NAME_SIZE_ON_SUSPENSION = L"CalculatorSizeOnSuspension";
constexpr auto EVENT_NAME_CALCULATOR_VIEWED_IN_SESSION = L"CalculatorViewedInSession";
constexpr auto EVENT_NAME_DATE_CALCULATOR_VIEWED_IN_SESSION = L"DateCalculatorViewedInSession";
constexpr auto EVENT_NAME_CONVERTER_VIEWED_IN_SESSION = L"ConverterViewedInSession";
constexpr auto EVENT_NAME_MODE_CHANGE_BEGIN = L"ModeChangeBegin";
constexpr auto EVENT_NAME_MODE_CHANGE_END = L"ModeChangeEnd";
constexpr auto EVENT_NAME_HISTORY_BODY_OPENED = L"HistoryBodyOpened";
constexpr auto EVENT_NAME_HISTORY_ITEM_LOAD_BEGIN = L"HistoryItemLoadBegin";
constexpr auto EVENT_NAME_HISTORY_ITEM_LOAD_END = L"HistoryItemLoadEnd";
constexpr auto EVENT_NAME_HISTORY_FLYOUT_OPEN_BEGIN = L"HistoryFlyoutOpenBegin";
constexpr auto EVENT_NAME_HISTORY_FLYOUT_OPEN_END = L"HistoryFlyoutOpenEnd";
constexpr auto EVENT_NAME_NEW_WINDOW_CREATION_BEGIN = L"NewWindowCreationBegin";
constexpr auto EVENT_NAME_NEW_WINDOW_CREATION_END = L"NewWindowCreationEnd";
constexpr auto EVENT_NAME_HISTORY_CLEAR = L"HistoryClearBegin";
constexpr auto EVENT_NAME_MULTIPLE_MEMORY_USED = L"MultipleMemoryUsed";
constexpr auto EVENT_NAME_SINGLE_MEMORY_USED = L"SingleMemoryUsed";
constexpr auto EVENT_NAME_SHARED_MEMORY_USED = L"SharedMemoryUsed";
constexpr auto EVENT_NAME_MEMORY_BODY_OPENED = L"MemoryBodyOpened";
constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_BEGIN = L"MemoryFlyoutOpenBegin";
constexpr auto EVENT_NAME_MEMORY_FLYOUT_OPEN_END = L"MemoryFlyoutOpenEnd";
constexpr auto EVENT_NAME_MEMORY_CLEAR_ALL = L"MemoryClearAll";
constexpr auto EVENT_NAME_INVALID_PASTED_INPUT_OCCURRED = L"InvalidPastedInputOccurred";
constexpr auto EVENT_NAME_VALID_INPUT_PASTED = L"ValidInputPasted";
constexpr auto EVENT_NAME_BITFLIP_PANE_CLICKED = L"BitFlipPaneClicked";
constexpr auto EVENT_NAME_BITFLIP_BUTTONS_USED = L"BitFlipToggleButtonUsed";
constexpr auto EVENT_NAME_ANGLE_BUTTONS_USED = L"AngleButtonUsedInSession";
constexpr auto EVENT_NAME_HYP_BUTTON_USED = L"HypButtonUsedInSession";
constexpr auto EVENT_NAME_FUNCTION_USAGE = L"FunctionUsageInSession";
constexpr auto EVENT_NAME_BITLENGTH_BUTTON_USED = L"BitLengthButtonUsed";
constexpr auto EVENT_NAME_RADIX_BUTTON_USED = L"RadixButtonUsed";
constexpr auto EVENT_NAME_MAX_WINDOW_COUNT = L"MaxWindowCountInSession";
constexpr auto EVENT_NAME_WINDOW_LAUNCHED_PROTOCOL = L"WindowActivatedThroughProtocol";
constexpr auto EVENT_NAME_WINDOW_LAUNCHED_TILESEARCH = L"WindowLaunchedThroughTile";
constexpr auto EVENT_NAME_DATE_DIFFERENCE_USED = L"DateDifferenceModeUsed";
constexpr auto EVENT_NAME_DATE_ADD_SUBTRACT_USED = L"DateAddSubtractModeUsed";
constexpr auto EVENT_NAME_DATE_DIFFERENCE_FOUND = L"DateDifferenceFound";
constexpr auto EVENT_NAME_HIDE_IF_SHOWN = L"HideIfShown";
constexpr auto EVENT_NAME_ABOUT_FLYOUT_OPENED = L"AboutFlyoutOpened";
constexpr auto EVENT_NAME_NAV_BAR_OPENED = L"NavBarOpened";
constexpr auto EVENT_NAME_CORE_WINDOW_WAS_NULL = L"CoreWindowWasNull";
constexpr auto EVENT_NAME_EXCEPTION = L"Exception";
constexpr auto EVENT_NAME_EXCEPTION = L"Exception";
constexpr auto PDT_PRIVACY_DATA_TAG = L"PartA_PrivTags";
constexpr auto PDT_PRODUCT_AND_SERVICE_USAGE = 0x0000'0000'0200'0000u;
constexpr auto PDT_PRIVACY_DATA_TAG = L"PartA_PrivTags";
constexpr auto PDT_PRODUCT_AND_SERVICE_USAGE = 0x0000'0000'0200'0000u;
#ifdef SEND_TELEMETRY
// c.f. WINEVENT_KEYWORD_RESERVED_63-56 0xFF00000000000000 // Bits 63-56 - channel keywords
// c.f. WINEVENT_KEYWORD_* 0x00FF000000000000 // Bits 55-48 - system-reserved keywords
constexpr int64_t MICROSOFT_KEYWORD_CRITICAL_DATA = 0x0000800000000000; // Bit 47
constexpr int64_t MICROSOFT_KEYWORD_MEASURES = 0x0000400000000000; // Bit 46
constexpr int64_t MICROSOFT_KEYWORD_TELEMETRY = 0x0000200000000000; // Bit 45
constexpr int64_t MICROSOFT_KEYWORD_RESERVED_44 = 0x0000100000000000; // Bit 44 (reserved for future assignment)
constexpr int64_t MICROSOFT_KEYWORD_MEASURES = 0x0000400000000000; // Bit 46
constexpr int64_t MICROSOFT_KEYWORD_TELEMETRY = 0x0000200000000000; // Bit 45
constexpr int64_t MICROSOFT_KEYWORD_RESERVED_44 = 0x0000100000000000; // Bit 44 (reserved for future assignment)
#else
// define all Keyword options as 0 when we do not want to upload app telemetry
constexpr int64_t MICROSOFT_KEYWORD_CRITICAL_DATA = 0;
@@ -99,11 +97,12 @@ namespace CalculatorApp
#pragma region TraceLogger setup and cleanup
TraceLogger::TraceLogger() :
g_calculatorProvider(
TraceLogger::TraceLogger()
: g_calculatorProvider(
L"MicrosoftCalculator",
LoggingChannelOptions(GUID{ 0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba }), // Microsoft Telemetry group
GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 }), // Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0}
GUID{ 0x905ca09, 0x610e, 0x401e, 0xb6, 0x50, 0x2f, 0x21, 0x29, 0x80, 0xb9, 0xe0 })
, // Unique providerID {0905CA09-610E-401E-B650-2F212980B9E0}
m_appLaunchActivity{ nullptr }
{
// initialize the function array
@@ -307,7 +306,8 @@ namespace CalculatorApp
void TraceLogger::LogSharedMemoryUsed(wstring_view fromMode, wstring_view toMode, unsigned int memorySize) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddString(L"FromMode", fromMode);
@@ -318,7 +318,8 @@ namespace CalculatorApp
void TraceLogger::LogBitFlipPaneClicked() const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_BITFLIP_PANE_CLICKED, fields);
@@ -326,7 +327,8 @@ namespace CalculatorApp
void TraceLogger::LogBitFlipUsed() const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_BITFLIP_BUTTONS_USED, fields);
@@ -339,11 +341,8 @@ namespace CalculatorApp
if (!isAppLaunchBeginLogged)
{
m_appLaunchActivity = g_calculatorProvider.StartActivity(
EVENT_NAME_APP_LAUNCH_BEGIN,
nullptr,
LoggingLevel::Verbose,
LoggingOptions(MICROSOFT_KEYWORD_TELEMETRY));
m_appLaunchActivity =
g_calculatorProvider.StartActivity(EVENT_NAME_APP_LAUNCH_BEGIN, nullptr, LoggingLevel::Verbose, LoggingOptions(MICROSOFT_KEYWORD_TELEMETRY));
isAppLaunchBeginLogged = true;
}
@@ -376,7 +375,8 @@ namespace CalculatorApp
void TraceLogger::LogDebug(wstring_view debugData)
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddString(L"DebugData", debugData);
@@ -385,7 +385,8 @@ namespace CalculatorApp
void TraceLogger::LogOnAppLaunch(wstring_view previousExecutionState) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddString(L"PreviousExecutionState", previousExecutionState);
@@ -394,7 +395,8 @@ namespace CalculatorApp
void TraceLogger::LogAboutFlyoutOpened() const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_ABOUT_FLYOUT_OPENED, fields);
@@ -402,7 +404,8 @@ namespace CalculatorApp
void TraceLogger::LogNavBarOpened() const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_NAV_BAR_OPENED, fields);
@@ -410,7 +413,8 @@ namespace CalculatorApp
void TraceLogger::LogClearHistory() const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_HISTORY_CLEAR, fields);
@@ -418,7 +422,8 @@ namespace CalculatorApp
void TraceLogger::LogHistoryFlyoutOpenBegin(unsigned int historyItemCount) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
// we want to record the event only when history item count is atleast 20
if (historyItemCount >= 20)
@@ -431,7 +436,8 @@ namespace CalculatorApp
void TraceLogger::LogHistoryFlyoutOpenEnd(int historyItemCount) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
if (historyItemCount >= 20)
{
@@ -443,7 +449,8 @@ namespace CalculatorApp
void TraceLogger::LogHistoryBodyOpened() const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_HISTORY_BODY_OPENED, fields);
@@ -451,7 +458,8 @@ namespace CalculatorApp
void TraceLogger::LogMemoryFlyoutOpenBegin(unsigned int memoryItemCount) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
// we want to record the event only when memory item count is atleast 4
if (memoryItemCount >= 4)
@@ -464,7 +472,8 @@ namespace CalculatorApp
void TraceLogger::LogMemoryFlyoutOpenEnd(unsigned int memoryItemCount) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
if (memoryItemCount >= 4)
{
@@ -476,7 +485,8 @@ namespace CalculatorApp
void TraceLogger::LogMemoryBodyOpened() const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_MEMORY_BODY_OPENED, fields);
@@ -487,7 +497,8 @@ namespace CalculatorApp
// Use of this function is to analyze perf of mode change.
void TraceLogger::LogModeChangeBegin(ViewMode fromMode, ViewMode toMode, int windowId)
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
if (NavCategory::IsValidViewMode(fromMode) && NavCategory::IsValidViewMode(toMode))
{
@@ -502,7 +513,8 @@ namespace CalculatorApp
// comment: same as LogModeChangeBegin
void TraceLogger::LogModeChangeEnd(ViewMode toMode, int windowId) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
if (NavCategory::IsValidViewMode(toMode))
{
@@ -515,7 +527,8 @@ namespace CalculatorApp
void TraceLogger::LogHistoryItemLoadBegin() const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_HISTORY_ITEM_LOAD_BEGIN, fields);
@@ -523,7 +536,8 @@ namespace CalculatorApp
void TraceLogger::LogHistoryItemLoadEnd(unsigned int historyTokenCount) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddUInt32(L"HistoryTokenCount", historyTokenCount);
@@ -532,7 +546,8 @@ namespace CalculatorApp
void TraceLogger::LogNewWindowCreationBegin(int windowId)
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddUInt32(L"WindowId", windowId);
@@ -541,7 +556,8 @@ namespace CalculatorApp
void TraceLogger::LogNewWindowCreationEnd(int windowId)
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddUInt32(L"WindowId", windowId);
@@ -550,7 +566,8 @@ namespace CalculatorApp
void TraceLogger::LogError(wstring_view errorString)
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddString(L"ErrorString", errorString);
@@ -559,7 +576,8 @@ namespace CalculatorApp
void TraceLogger::LogPrelaunchedAppActivatedByUser()
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_PRELAUNCHED_APP_ACTIVATED_BY_USER, fields);
@@ -567,7 +585,8 @@ namespace CalculatorApp
void TraceLogger::LogAppPrelaunchedBySystem()
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_APP_PRELAUNCHED_BY_SYSTEM, fields);
@@ -588,9 +607,11 @@ namespace CalculatorApp
}
}
void TraceLogger::LogMemoryUsed(int windowId, unsigned int slotPosition, bool isStandard, bool isScientific, bool isProgrammer, unsigned int memorySize) const
void TraceLogger::LogMemoryUsed(int windowId, unsigned int slotPosition, bool isStandard, bool isScientific, bool isProgrammer,
unsigned int memorySize) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
// Reader lock for the static resources
reader_writer_lock::scoped_lock_read lock(s_traceLoggerLock);
@@ -625,7 +646,8 @@ namespace CalculatorApp
void TraceLogger::LogMultipleMemoryUsed(unsigned int slotPosition, unsigned int memorySize) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddUInt32(L"MemoryIndex", slotPosition);
@@ -635,7 +657,8 @@ namespace CalculatorApp
void TraceLogger::LogSingleMemoryUsed(unsigned int memorySize) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddUInt32(L"MemoryListSize", memorySize);
@@ -644,7 +667,8 @@ namespace CalculatorApp
void TraceLogger::LogInvalidPastedInputOccurred(wstring_view reason, ViewMode mode, int programmerNumberBase, int bitLengthType)
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddString(L"Mode", NavCategory::GetFriendlyName(mode)->Data());
@@ -657,7 +681,8 @@ namespace CalculatorApp
void TraceLogger::LogValidInputPasted(ViewMode mode) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddString(L"Mode", NavCategory::GetFriendlyName(mode)->Data());
@@ -666,7 +691,8 @@ namespace CalculatorApp
void TraceLogger::LogStandardException(wstring_view functionName, const exception& e) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddString(L"FunctionName", functionName);
@@ -678,7 +704,8 @@ namespace CalculatorApp
void TraceLogger::LogWinRTException(wstring_view functionName, hresult_error const& e) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddString(L"FunctionName", functionName);
@@ -687,9 +714,10 @@ namespace CalculatorApp
LogMeasureEvent(EVENT_NAME_EXCEPTION, fields);
}
void TraceLogger::LogPlatformException(wstring_view functionName, Platform::Exception^ e) const
void TraceLogger::LogPlatformException(wstring_view functionName, Platform::Exception ^ e) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddString(L"FunctionName", functionName);
@@ -733,11 +761,11 @@ namespace CalculatorApp
{
return s_programmerType[index];
}
//return "N/A"
// return "N/A"
return s_programmerType[0];
}
bool TraceLogger::GetIndex(int &index)
bool TraceLogger::GetIndex(int& index)
{
if (findIndex[index] > 0)
{
@@ -755,7 +783,8 @@ namespace CalculatorApp
void TraceLogger::LogMaxWindowCount()
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
fields.AddUInt32(L"WindowCount", (unsigned int)maxWindowCount);
@@ -764,7 +793,8 @@ namespace CalculatorApp
void TraceLogger::LogWindowActivated() const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_WINDOW_LAUNCHED_PROTOCOL, fields);
@@ -772,7 +802,8 @@ namespace CalculatorApp
void TraceLogger::LogWindowLaunched() const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_WINDOW_LAUNCHED_TILESEARCH, fields);
@@ -840,7 +871,8 @@ namespace CalculatorApp
void TraceLogger::LogFunctionUsage(int windowId)
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
for (int i = 0; i < functionCount; i++)
{
@@ -897,8 +929,7 @@ namespace CalculatorApp
// Ignore first 3 calls during the initialization of the combo box selected items for Add mode
int firstChangeEventCount = isAddMode ? 4 : 1;
if (((*usageMap)[windowId] == firstChangeEventCount)
&& (!(*isLoggedInSession)))
if (((*usageMap)[windowId] == firstChangeEventCount) && (!(*isLoggedInSession)))
{
LoggingFields fields{};
fields.AddString(L"AddSubtractMode", isAddMode ? L"Add" : L"Subtract");
@@ -910,16 +941,12 @@ namespace CalculatorApp
void TraceLogger::LogDateClippedTimeDifferenceFound(Calendar const& today, DateTime const& clippedTime) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
auto calendarSystem = today.GetCalendarSystem();
auto clock = today.GetClock();
DateTimeFormatter dtFormatter{
L"longdate shorttime",
{ L"en-US" },
GlobalizationPreferences::HomeGeographicRegion(),
calendarSystem,
clock };
DateTimeFormatter dtFormatter{ L"longdate shorttime", { L"en-US" }, GlobalizationPreferences::HomeGeographicRegion(), calendarSystem, clock };
LoggingFields fields{};
fields.AddString(L"ResolvedCalendarLanguage", today.ResolvedLanguage());
@@ -934,7 +961,8 @@ namespace CalculatorApp
void TraceLogger::LogUserRequestedRefreshFailed() const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(L"UserRequestedRefreshFailed", fields);
@@ -942,7 +970,8 @@ namespace CalculatorApp
void TraceLogger::LogConversionResult(wstring_view fromValue, wstring_view fromUnit, wstring_view toValue, wstring_view toUnit) const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
wstring behaviorString{};
NetworkAccessBehavior behavior = NetworkManager::GetNetworkAccessBehavior();
@@ -979,10 +1008,10 @@ namespace CalculatorApp
void TraceLogger::LogCoreWindowWasNull() const
{
if (!GetTraceLoggingProviderEnabled()) return;
if (!GetTraceLoggingProviderEnabled())
return;
LoggingFields fields{};
LogTelemetryEvent(EVENT_NAME_CORE_WINDOW_WAS_NULL, fields);
}
}

View File

@@ -18,7 +18,10 @@ namespace CalculatorApp
public:
int count;
std::wstring funcName;
FuncLog() { count = 0; }
FuncLog()
{
count = 0;
}
FuncLog(std::wstring fName)
{
funcName = fName;
@@ -30,7 +33,7 @@ namespace CalculatorApp
{
public:
TraceLogger(_In_ TraceLogger const&) = delete;
TraceLogger const & operator= (_In_ TraceLogger const&) = delete;
TraceLogger const& operator=(_In_ TraceLogger const&) = delete;
~TraceLogger();
static TraceLogger& GetInstance();
bool GetTraceLoggingProviderEnabled() const;
@@ -93,21 +96,22 @@ namespace CalculatorApp
// Trace methods for Date Calculator usage
void LogDateDifferenceModeUsed(int windowId);
void LogDateAddSubtractModeUsed(int windowId, bool isAddMode);
void LogDateClippedTimeDifferenceFound(winrt::Windows::Globalization::Calendar const& today, winrt::Windows::Foundation::DateTime const& clippedTime) const;
void LogDateClippedTimeDifferenceFound(winrt::Windows::Globalization::Calendar const& today,
winrt::Windows::Foundation::DateTime const& clippedTime) const;
void LogStandardException(std::wstring_view functionName, _In_ const std::exception& e) const;
void LogWinRTException(std::wstring_view functionName, _In_ winrt::hresult_error const& e) const;
void LogPlatformException(std::wstring_view functionName, _In_ Platform::Exception^ e) const;
void LogPlatformException(std::wstring_view functionName, _In_ Platform::Exception ^ e) const;
private:
// Create an instance of TraceLogger
TraceLogger();
// Any new Log method should
// a) decide the level of logging. This will help us in limiting recording of events only up to a certain level. See this link for guidance https://msdn.microsoft.com/en-us/library/windows/desktop/aa363742(v=vs.85).aspx
// We're using Verbose level for events that are called frequently and needed only for debugging or capturing perf for specific scenarios
// b) should decide whether or not to log to telemetry and pass TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY) accordingly
// c) Should accept a variable number of additional data arguments if needed
// a) decide the level of logging. This will help us in limiting recording of events only up to a certain level. See this link for guidance
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363742(v=vs.85).aspx We're using Verbose level for events that are called frequently and
// needed only for debugging or capturing perf for specific scenarios b) should decide whether or not to log to telemetry and pass
// TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY) accordingly c) Should accept a variable number of additional data arguments if needed
void LogTelemetryEvent(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const;
void LogMeasureEvent(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const;
void LogCriticalDataEvent(std::wstring_view eventName, winrt::Windows::Foundation::Diagnostics::LoggingFields fields) const;
@@ -133,7 +137,7 @@ namespace CalculatorApp
bool isHypButtonLogged = false;
bool isAngleButtonInitialized = false;
unsigned int findIndex[maxFunctionSize] = { 0 };
bool GetIndex(int &index);
bool GetIndex(int& index);
std::wstring GetProgrammerType(int index);
size_t maxWindowCount = 0;
bool isAppLaunchBeginLogged = false;

View File

@@ -30,12 +30,12 @@ void Utils::IFTPlatformException(HRESULT hr)
{
if (FAILED(hr))
{
Platform::Exception^ exception = ref new Platform::Exception(hr);
Platform::Exception ^ exception = ref new Platform::Exception(hr);
throw(exception);
}
}
String^ Utils::GetStringValue(String^ input)
String ^ Utils::GetStringValue(String ^ input)
{
// Remove first and last " characters
if (input->Length() >= 3)
@@ -68,20 +68,16 @@ int Utils::GetWindowId()
return windowId;
}
void Utils::RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ CoreDispatcher^ currentDispatcher)
void Utils::RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ CoreDispatcher ^ currentDispatcher)
{
if (currentDispatcher != nullptr)
{
auto task = create_task(currentDispatcher->RunAsync(CoreDispatcherPriority::Normal,
ref new DispatchedHandler([function]()
{
function();
})));
auto task = create_task(currentDispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new DispatchedHandler([function]() { function(); })));
}
}
// Returns if the last character of a wstring is the target wchar_t
bool Utils::IsLastCharacterTarget(_In_ wstring const &input, _In_ wchar_t target)
bool Utils::IsLastCharacterTarget(_In_ wstring const& input, _In_ wchar_t target)
{
return !input.empty() && input.back() == target;
}
@@ -96,9 +92,8 @@ wstring Utils::RemoveUnwantedCharsFromWstring(wstring input, wchar_t* unwantedCh
return input;
}
void Utils::SerializeCommandsAndTokens(_In_ shared_ptr<CalculatorVector <pair<wstring, int>>> const &tokens,
_In_ shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> const &commands,
DataWriter^ writer)
void Utils::SerializeCommandsAndTokens(_In_ shared_ptr<CalculatorVector<pair<wstring, int>>> const& tokens,
_In_ shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> const& commands, DataWriter ^ writer)
{
unsigned int commandsSize;
IFTPlatformException(commands->GetSize(&commandsSize));
@@ -134,7 +129,7 @@ void Utils::SerializeCommandsAndTokens(_In_ shared_ptr<CalculatorVector <pair<ws
}
}
const shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> Utils::DeserializeCommands(DataReader^ reader)
const shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> Utils::DeserializeCommands(DataReader ^ reader)
{
shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> commandVector = make_shared<CalculatorVector<shared_ptr<IExpressionCommand>>>();
auto commandVectorSize = reader->ReadUInt32();
@@ -151,9 +146,9 @@ const shared_ptr<CalculatorVector<shared_ptr<IExpressionCommand>>> Utils::Deseri
return commandVector;
}
const shared_ptr<CalculatorVector <pair<wstring, int>>> Utils::DeserializeTokens(DataReader^ reader)
const shared_ptr<CalculatorVector<pair<wstring, int>>> Utils::DeserializeTokens(DataReader ^ reader)
{
shared_ptr<CalculatorVector <pair<wstring, int>>> tokenVector = make_shared<CalculatorVector<pair<wstring, int>>>();
shared_ptr<CalculatorVector<pair<wstring, int>>> tokenVector = make_shared<CalculatorVector<pair<wstring, int>>>();
auto tokensSize = reader->ReadUInt32();
for (unsigned int i = 0; i < tokensSize; ++i)
@@ -193,14 +188,14 @@ bool Utils::IsDateTimeOlderThan(DateTime dateTime, const long long duration)
return dateTime.UniversalTime + duration < now.UniversalTime;
}
task<void> Utils::WriteFileToFolder(IStorageFolder^ folder, String^ fileName, String^ contents, CreationCollisionOption collisionOption)
task<void> Utils::WriteFileToFolder(IStorageFolder ^ folder, String ^ fileName, String ^ contents, CreationCollisionOption collisionOption)
{
if (folder == nullptr)
{
co_return;
}
StorageFile^ file = co_await folder->CreateFileAsync(fileName, collisionOption);
StorageFile ^ file = co_await folder->CreateFileAsync(fileName, collisionOption);
if (file == nullptr)
{
co_return;
@@ -209,19 +204,19 @@ task<void> Utils::WriteFileToFolder(IStorageFolder^ folder, String^ fileName, St
co_await FileIO::WriteTextAsync(file, contents);
}
task<String^> Utils::ReadFileFromFolder(IStorageFolder^ folder, String^ fileName)
task<String ^> Utils::ReadFileFromFolder(IStorageFolder ^ folder, String ^ fileName)
{
if (folder == nullptr)
{
co_return nullptr;
}
StorageFile^ file = co_await folder->GetFileAsync(fileName);
StorageFile ^ file = co_await folder->GetFileAsync(fileName);
if (file == nullptr)
{
co_return nullptr;
}
String^ contents = co_await FileIO::ReadTextAsync(file);
String ^ contents = co_await FileIO::ReadTextAsync(file);
co_return contents;
}

View File

@@ -9,92 +9,187 @@
// Utility macros to make Models easier to write
// generates a member variable called m_<n>
#define PROPERTY_R(t, n)\
property t n {\
t get() { return m_##n; }\
private: void set(t value) { m_##n = value; }\
} private: t m_##n; public:
#define PROPERTY_R(t, n) \
property t n \
{ \
t get() \
{ \
return m_##n; \
} \
\
private: \
void set(t value) \
{ \
m_##n = value; \
} \
} \
\
private: \
t m_##n; \
\
public:
#define PROPERTY_RW(t, n)\
property t n {\
t get() { return m_##n; }\
void set(t value) { m_##n = value; }\
} private: t m_##n; public:
#define PROPERTY_RW(t, n) \
property t n \
{ \
t get() \
{ \
return m_##n; \
} \
void set(t value) \
{ \
m_##n = value; \
} \
} \
\
private: \
t m_##n; \
\
public:
#define OBSERVABLE_PROPERTY_R(t, n)\
property t n {\
t get() { return m_##n; }\
private: void set(t value) {\
if (m_##n != value) {\
m_##n = value;\
RaisePropertyChanged(L#n);\
}}\
} private: t m_##n; public:
#define OBSERVABLE_PROPERTY_R(t, n) \
property t n \
{ \
t get() \
{ \
return m_##n; \
} \
\
private: \
void set(t value) \
{ \
if (m_##n != value) \
{ \
m_##n = value; \
RaisePropertyChanged(L#n); \
} \
} \
} \
\
private: \
t m_##n; \
\
public:
#define OBSERVABLE_PROPERTY_RW(t, n)\
property t n {\
t get() { return m_##n; }\
void set(t value) {\
if (m_##n != value) {\
m_##n = value;\
RaisePropertyChanged(L#n);\
}\
}\
} private: t m_##n; public:
#define OBSERVABLE_PROPERTY_RW(t, n) \
property t n \
{ \
t get() \
{ \
return m_##n; \
} \
void set(t value) \
{ \
if (m_##n != value) \
{ \
m_##n = value; \
RaisePropertyChanged(L#n); \
} \
} \
} \
\
private: \
t m_##n; \
\
public:
#define OBSERVABLE_NAMED_PROPERTY_R(t, n)\
OBSERVABLE_PROPERTY_R(t, n)\
internal: static property Platform::String^ n##PropertyName {\
Platform::String^ get() { return Platform::StringReference(L#n); }\
} public:
#define OBSERVABLE_NAMED_PROPERTY_R(t, n) \
OBSERVABLE_PROPERTY_R(t, n) \
internal: \
static property Platform::String ^ n##PropertyName \
{ \
Platform::String ^ get() { return Platform::StringReference(L#n); } \
} \
\
public:
#define OBSERVABLE_NAMED_PROPERTY_RW(t, n)\
OBSERVABLE_PROPERTY_RW(t, n)\
internal: static property Platform::String^ n##PropertyName {\
Platform::String^ get() { return Platform::StringReference(L#n); }\
} public:
#define OBSERVABLE_NAMED_PROPERTY_RW(t, n) \
OBSERVABLE_PROPERTY_RW(t, n) \
internal: \
static property Platform::String ^ n##PropertyName \
{ \
Platform::String ^ get() { return Platform::StringReference(L#n); } \
} \
\
public:
#define OBSERVABLE_PROPERTY_FIELD(n) m_##n
// This variant of the observable object is for objects that don't want to react to property changes
#ifndef UNIT_TESTS
#define OBSERVABLE_OBJECT() virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\
internal: void RaisePropertyChanged(Platform::String^ p) {\
PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs(p)); } public:
#define OBSERVABLE_OBJECT() \
virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler ^ PropertyChanged; \
internal: \
void RaisePropertyChanged(Platform::String ^ p) \
{ \
PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs(p)); \
} \
\
public:
#else
#define OBSERVABLE_OBJECT() virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\
internal: void RaisePropertyChanged(Platform::String^ p) {\
} public:
#define OBSERVABLE_OBJECT() \
virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler ^ PropertyChanged; \
internal: \
void RaisePropertyChanged(Platform::String ^ p) \
{ \
} \
\
public:
#endif
// The callback specified in the macro is a method in the class that will be called every time the object changes
// the callback is supposed to be have a single parameter of type Platform::String^
#ifndef UNIT_TESTS
#define OBSERVABLE_OBJECT_CALLBACK(c) virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\
internal: void RaisePropertyChanged(Platform::String^ p) {\
PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs(p));\
c(p);\
} public:
#define OBSERVABLE_OBJECT_CALLBACK(c) \
virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler ^ PropertyChanged; \
internal: \
void RaisePropertyChanged(Platform::String ^ p) \
{ \
PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs(p)); \
c(p); \
} \
\
public:
#else
#define OBSERVABLE_OBJECT_CALLBACK(c) virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;\
internal: void RaisePropertyChanged(Platform::String^ p) {\
c(p);\
} public:
#define OBSERVABLE_OBJECT_CALLBACK(c) \
virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler ^ PropertyChanged; \
internal: \
void RaisePropertyChanged(Platform::String ^ p) \
{ \
c(p); \
} \
\
public:
#endif
// The variable member generated by this macro should not be used in the class code, use the
// property getter instead.
#define COMMAND_FOR_METHOD(p, m) property Windows::UI::Xaml::Input::ICommand^ p {\
#define COMMAND_FOR_METHOD(p, m) \
property Windows::UI::Xaml::Input::ICommand^ p {\
Windows::UI::Xaml::Input::ICommand^ get() {\
if (!donotuse_##p) {\
donotuse_##p = CalculatorApp::Common::MakeDelegate(this, &m);\
} return donotuse_##p; }} private: Windows::UI::Xaml::Input::ICommand^ donotuse_##p; public:
} return donotuse_##p; }} private: Windows::UI::Xaml::Input::ICommand^ donotuse_##p; \
\
public:
#define DEPENDENCY_PROPERTY_DECLARATION(t, n)\
property t n {\
t get() { return safe_cast<t>(GetValue(s_##n##Property)); }\
void set(t value) { SetValue(s_##n##Property, value); } }\
private: static Windows::UI::Xaml::DependencyProperty^ s_##n##Property; public:
#define DEPENDENCY_PROPERTY_DECLARATION(t, n) \
property t n \
{ \
t get() \
{ \
return safe_cast<t>(GetValue(s_##n##Property)); \
} \
void set(t value) \
{ \
SetValue(s_##n##Property, value); \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ s_##n##Property; \
\
public:
// Utilities for DependencyProperties
namespace Utils
@@ -114,13 +209,13 @@ namespace Utils
};
template <typename T>
struct RemoveHat<T^>
struct RemoveHat<T ^>
{
typedef T type;
};
template <typename T>
typename std::enable_if<IsRefClass<T>::value, T^>::type MakeDefault()
typename std::enable_if<IsRefClass<T>::value, T ^>::type MakeDefault()
{
return nullptr;
}
@@ -283,140 +378,317 @@ namespace Utils
}
void IFTPlatformException(HRESULT hr);
Platform::String^ GetStringValue(Platform::String^ input);
bool IsLastCharacterTarget(std::wstring const &input, wchar_t target);
Platform::String ^ GetStringValue(Platform::String ^ input);
bool IsLastCharacterTarget(std::wstring const& input, wchar_t target);
std::wstring RemoveUnwantedCharsFromWstring(std::wstring inputString, wchar_t* unwantedChars, unsigned int size);
double GetDoubleFromWstring(std::wstring input);
int GetWindowId();
void RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ Windows::UI::Core::CoreDispatcher^ currentDispatcher);
void SerializeCommandsAndTokens(_In_ std::shared_ptr<CalculatorVector <std::pair<std::wstring, int>>> const &tokens,
_In_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands,
Windows::Storage::Streams::DataWriter^ writer);
void RunOnUIThreadNonblocking(std::function<void()>&& function, _In_ Windows::UI::Core::CoreDispatcher ^ currentDispatcher);
void SerializeCommandsAndTokens(_In_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
_In_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands,
Windows::Storage::Streams::DataWriter ^ writer);
const std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> DeserializeCommands(Windows::Storage::Streams::DataReader^ reader);
const std::shared_ptr<CalculatorVector <std::pair<std::wstring, int>>> DeserializeTokens(Windows::Storage::Streams::DataReader^ reader);
const std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> DeserializeCommands(Windows::Storage::Streams::DataReader ^ reader);
const std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> DeserializeTokens(Windows::Storage::Streams::DataReader ^ reader);
Windows::Foundation::DateTime GetUniversalSystemTime();
bool IsDateTimeOlderThan(Windows::Foundation::DateTime dateTime, const long long duration);
concurrency::task<void> WriteFileToFolder(Windows::Storage::IStorageFolder^ folder, Platform::String^ fileName, Platform::String^ contents, Windows::Storage::CreationCollisionOption collisionOption);
concurrency::task<Platform::String^> ReadFileFromFolder(Windows::Storage::IStorageFolder^ folder, Platform::String^ fileName);
concurrency::task<void> WriteFileToFolder(Windows::Storage::IStorageFolder ^ folder, Platform::String ^ fileName, Platform::String ^ contents,
Windows::Storage::CreationCollisionOption collisionOption);
concurrency::task<Platform::String ^> ReadFileFromFolder(Windows::Storage::IStorageFolder ^ folder, Platform::String ^ fileName);
}
// This goes into the header to define the property, in the public: section of the class
#define DEPENDENCY_PROPERTY_OWNER(owner)\
private: typedef owner DependencyPropertiesOwner; public:
#define DEPENDENCY_PROPERTY_OWNER(owner) \
private: \
typedef owner DependencyPropertiesOwner; \
\
public:
// Normal DependencyProperty
#define DEPENDENCY_PROPERTY(type, name)\
property type name {\
type get() { return safe_cast<type>(GetValue(s_##name##Property)); }\
void set(type value) { SetValue(s_##name##Property, value); }\
} private: static Windows::UI::Xaml::DependencyProperty^ s_##name##Property;\
public: static property Windows::UI::Xaml::DependencyProperty^ name##Property {\
Windows::UI::Xaml::DependencyProperty^ get() { assert(s_##name##Property); return s_##name##Property; }\
}\
private: static Windows::UI::Xaml::DependencyProperty^ Initialize##name##Property() {\
return Utils::RegisterDependencyProperty<DependencyPropertiesOwner, type>(L#name); } public:
#define DEPENDENCY_PROPERTY(type, name) \
property type name \
{ \
type get() \
{ \
return safe_cast<type>(GetValue(s_##name##Property)); \
} \
void set(type value) \
{ \
SetValue(s_##name##Property, value); \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ s_##name##Property; \
\
public: \
static property Windows::UI::Xaml::DependencyProperty ^ name##Property \
{ \
Windows::UI::Xaml::DependencyProperty ^ get() { \
assert(s_##name##Property); \
return s_##name##Property; \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ Initialize##name##Property() \
{ \
return Utils::RegisterDependencyProperty<DependencyPropertiesOwner, type>(L#name); \
} \
\
public:
#define DEPENDENCY_PROPERTY_WITH_DEFAULT(type, name, defaultValue)\
property type name {\
type get() { return safe_cast<type>(GetValue(s_##name##Property)); }\
void set(type value) { SetValue(s_##name##Property, value); }\
} private: static Windows::UI::Xaml::DependencyProperty^ s_##name##Property;\
public: static property Windows::UI::Xaml::DependencyProperty^ name##Property {\
Windows::UI::Xaml::DependencyProperty^ get() { assert(s_##name##Property); return s_##name##Property; }\
}\
private: static Windows::UI::Xaml::DependencyProperty^ Initialize##name##Property() {\
return Utils::RegisterDependencyProperty<DependencyPropertiesOwner, type>(L#name, defaultValue); } public:
#define DEPENDENCY_PROPERTY_WITH_DEFAULT(type, name, defaultValue) \
property type name \
{ \
type get() \
{ \
return safe_cast<type>(GetValue(s_##name##Property)); \
} \
void set(type value) \
{ \
SetValue(s_##name##Property, value); \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ s_##name##Property; \
\
public: \
static property Windows::UI::Xaml::DependencyProperty ^ name##Property \
{ \
Windows::UI::Xaml::DependencyProperty ^ get() { \
assert(s_##name##Property); \
return s_##name##Property; \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ Initialize##name##Property() \
{ \
return Utils::RegisterDependencyProperty<DependencyPropertiesOwner, type>(L#name, defaultValue); \
} \
\
public:
#define DEPENDENCY_PROPERTY_WITH_CALLBACK(type, name)\
property type name {\
type get() { return safe_cast<type>(GetValue(s_##name##Property)); }\
void set(type value) { SetValue(s_##name##Property, value); }\
} private: static Windows::UI::Xaml::DependencyProperty^ s_##name##Property;\
public: static property Windows::UI::Xaml::DependencyProperty^ name##Property {\
Windows::UI::Xaml::DependencyProperty^ get() { assert(s_##name##Property); return s_##name##Property; }\
}\
private: static Windows::UI::Xaml::DependencyProperty^ Initialize##name##Property() {\
return Utils::RegisterDependencyPropertyWithCallback<DependencyPropertiesOwner, type>(L#name, &On##name##PropertyChangedImpl); }\
static void On##name##PropertyChangedImpl(Windows::UI::Xaml::DependencyObject^ sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ args) {\
auto self = safe_cast<DependencyPropertiesOwner^>(sender);\
self->On##name##PropertyChanged(safe_cast<type>(args->OldValue), safe_cast<type>(args->NewValue)); } public:
#define DEPENDENCY_PROPERTY_WITH_CALLBACK(type, name) \
property type name \
{ \
type get() \
{ \
return safe_cast<type>(GetValue(s_##name##Property)); \
} \
void set(type value) \
{ \
SetValue(s_##name##Property, value); \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ s_##name##Property; \
\
public: \
static property Windows::UI::Xaml::DependencyProperty ^ name##Property \
{ \
Windows::UI::Xaml::DependencyProperty ^ get() { \
assert(s_##name##Property); \
return s_##name##Property; \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ Initialize##name##Property() \
{ \
return Utils::RegisterDependencyPropertyWithCallback<DependencyPropertiesOwner, type>(L#name, &On##name##PropertyChangedImpl); \
} \
static void On##name##PropertyChangedImpl(Windows::UI::Xaml::DependencyObject ^ sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ args) \
{ \
auto self = safe_cast<DependencyPropertiesOwner ^>(sender); \
self->On##name##PropertyChanged(safe_cast<type>(args->OldValue), safe_cast<type>(args->NewValue)); \
} \
\
public:
#define DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(type, name, defaultValue)\
property type name {\
type get() { return safe_cast<type>(GetValue(s_##name##Property)); }\
void set(type value) { SetValue(s_##name##Property, value); }\
} private: static Windows::UI::Xaml::DependencyProperty^ s_##name##Property;\
public: static property Windows::UI::Xaml::DependencyProperty^ name##Property {\
Windows::UI::Xaml::DependencyProperty^ get() { assert(s_##name##Property); return s_##name##Property; }\
}\
private: static Windows::UI::Xaml::DependencyProperty^ Initialize##name##Property() {\
return Utils::RegisterDependencyPropertyWithCallback<DependencyPropertiesOwner, type>(L#name, defaultValue, &On##name##PropertyChangedImpl); }\
static void On##name##PropertyChangedImpl(Windows::UI::Xaml::DependencyObject^ sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ args) {\
auto self = safe_cast<DependencyPropertiesOwner^>(sender);\
self->On##name##PropertyChanged(safe_cast<type>(args->OldValue), safe_cast<type>(args->NewValue)); } public:
#define DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(type, name, defaultValue) \
property type name \
{ \
type get() \
{ \
return safe_cast<type>(GetValue(s_##name##Property)); \
} \
void set(type value) \
{ \
SetValue(s_##name##Property, value); \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ s_##name##Property; \
\
public: \
static property Windows::UI::Xaml::DependencyProperty ^ name##Property \
{ \
Windows::UI::Xaml::DependencyProperty ^ get() { \
assert(s_##name##Property); \
return s_##name##Property; \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ Initialize##name##Property() \
{ \
return Utils::RegisterDependencyPropertyWithCallback<DependencyPropertiesOwner, type>(L#name, defaultValue, &On##name##PropertyChangedImpl); \
} \
static void On##name##PropertyChangedImpl(Windows::UI::Xaml::DependencyObject ^ sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ args) \
{ \
auto self = safe_cast<DependencyPropertiesOwner ^>(sender); \
self->On##name##PropertyChanged(safe_cast<type>(args->OldValue), safe_cast<type>(args->NewValue)); \
} \
\
public:
// Attached DependencyProperty
#define DEPENDENCY_PROPERTY_ATTACHED(type, name)\
static type Get##name(Windows::UI::Xaml::DependencyObject^ target) { return safe_cast<type>(target->GetValue(s_##name##Property)); }\
static void Set##name(Windows::UI::Xaml::DependencyObject^ target, type value) { target->SetValue(s_##name##Property, value); }\
private: static Windows::UI::Xaml::DependencyProperty^ s_##name##Property;\
public: static property Windows::UI::Xaml::DependencyProperty^ name##Property {\
Windows::UI::Xaml::DependencyProperty^ get() { assert(s_##name##Property); return s_##name##Property; }\
}\
private: static Windows::UI::Xaml::DependencyProperty^ Initialize##name##Property() {\
return Utils::RegisterDependencyPropertyAttached<DependencyPropertiesOwner, type>(L#name); } public:
#define DEPENDENCY_PROPERTY_ATTACHED(type, name) \
static type Get##name(Windows::UI::Xaml::DependencyObject ^ target) \
{ \
return safe_cast<type>(target->GetValue(s_##name##Property)); \
} \
static void Set##name(Windows::UI::Xaml::DependencyObject ^ target, type value) \
{ \
target->SetValue(s_##name##Property, value); \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ s_##name##Property; \
\
public: \
static property Windows::UI::Xaml::DependencyProperty ^ name##Property \
{ \
Windows::UI::Xaml::DependencyProperty ^ get() { \
assert(s_##name##Property); \
return s_##name##Property; \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ Initialize##name##Property() \
{ \
return Utils::RegisterDependencyPropertyAttached<DependencyPropertiesOwner, type>(L#name); \
} \
\
public:
#define DEPENDENCY_PROPERTY_ATTACHED_WITH_DEFAULT(type, name, defaultValue)\
static type Get##name(Windows::UI::Xaml::DependencyObject^ target) { return safe_cast<type>(target->GetValue(s_##name##Property)); }\
static void Set##name(Windows::UI::Xaml::DependencyObject^ target, type value) { target->SetValue(s_##name##Property, value); }\
private: static Windows::UI::Xaml::DependencyProperty^ s_##name##Property;\
public: static property Windows::UI::Xaml::DependencyProperty^ name##Property {\
Windows::UI::Xaml::DependencyProperty^ get() { assert(s_##name##Property); return s_##name##Property; }\
}\
private: static Windows::UI::Xaml::DependencyProperty^ Initialize##name##Property() {\
return Utils::RegisterDependencyPropertyAttached<DependencyPropertiesOwner, type>(L#name, defaultValue); } public:
#define DEPENDENCY_PROPERTY_ATTACHED_WITH_DEFAULT(type, name, defaultValue) \
static type Get##name(Windows::UI::Xaml::DependencyObject ^ target) \
{ \
return safe_cast<type>(target->GetValue(s_##name##Property)); \
} \
static void Set##name(Windows::UI::Xaml::DependencyObject ^ target, type value) \
{ \
target->SetValue(s_##name##Property, value); \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ s_##name##Property; \
\
public: \
static property Windows::UI::Xaml::DependencyProperty ^ name##Property \
{ \
Windows::UI::Xaml::DependencyProperty ^ get() { \
assert(s_##name##Property); \
return s_##name##Property; \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ Initialize##name##Property() \
{ \
return Utils::RegisterDependencyPropertyAttached<DependencyPropertiesOwner, type>(L#name, defaultValue); \
} \
\
public:
#define DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(type, name)\
static type Get##name(Windows::UI::Xaml::DependencyObject^ target) { return safe_cast<type>(target->GetValue(s_##name##Property)); }\
static void Set##name(Windows::UI::Xaml::DependencyObject^ target, type value) { target->SetValue(s_##name##Property, value); }\
private: static Windows::UI::Xaml::DependencyProperty^ s_##name##Property;\
public: static property Windows::UI::Xaml::DependencyProperty^ name##Property {\
Windows::UI::Xaml::DependencyProperty^ get() { assert(s_##name##Property); return s_##name##Property; }\
}\
private: static Windows::UI::Xaml::DependencyProperty^ Initialize##name##Property() {\
return Utils::RegisterDependencyPropertyAttachedWithCallback<DependencyPropertiesOwner, type>(L#name, &On##name##PropertyChangedImpl); }\
static void On##name##PropertyChangedImpl(Windows::UI::Xaml::DependencyObject^ sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ args) {\
On##name##PropertyChanged(sender, safe_cast<type>(args->OldValue), safe_cast<type>(args->NewValue)); } public:
#define DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(type, name) \
static type Get##name(Windows::UI::Xaml::DependencyObject ^ target) \
{ \
return safe_cast<type>(target->GetValue(s_##name##Property)); \
} \
static void Set##name(Windows::UI::Xaml::DependencyObject ^ target, type value) \
{ \
target->SetValue(s_##name##Property, value); \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ s_##name##Property; \
\
public: \
static property Windows::UI::Xaml::DependencyProperty ^ name##Property \
{ \
Windows::UI::Xaml::DependencyProperty ^ get() { \
assert(s_##name##Property); \
return s_##name##Property; \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ Initialize##name##Property() \
{ \
return Utils::RegisterDependencyPropertyAttachedWithCallback<DependencyPropertiesOwner, type>(L#name, &On##name##PropertyChangedImpl); \
} \
static void On##name##PropertyChangedImpl(Windows::UI::Xaml::DependencyObject ^ sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ args) \
{ \
On##name##PropertyChanged(sender, safe_cast<type>(args->OldValue), safe_cast<type>(args->NewValue)); \
} \
\
public:
#define DEPENDENCY_PROPERTY_ATTACHED_WITH_DEFAULT_AND_CALLBACK(type, name, defaultValue)\
static type Get##name(Windows::UI::Xaml::DependencyObject^ target) { return safe_cast<type>(target->GetValue(s_##name##Property)); }\
static void Set##name(Windows::UI::Xaml::DependencyObject^ target, type value) { target->SetValue(s_##name##Property, value); }\
private: static Windows::UI::Xaml::DependencyProperty^ s_##name##Property;\
public: static property Windows::UI::Xaml::DependencyProperty^ name##Property {\
Windows::UI::Xaml::DependencyProperty^ get() { assert(s_##name##Property); return s_##name##Property; }\
}\
private: static Windows::UI::Xaml::DependencyProperty^ Initialize##name##Property() {\
return Utils::RegisterDependencyPropertyAttachedWithCallback<DependencyPropertiesOwner, type>(L#name, defaultValue, &On##name##PropertyChangedImpl); }\
static void On##name##PropertyChangedImpl(Windows::UI::Xaml::DependencyObject^ sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ args) {\
On##name##PropertyChanged(sender, safe_cast<type>(args->OldValue), safe_cast<type>(args->NewValue)); } public:
#define DEPENDENCY_PROPERTY_ATTACHED_WITH_DEFAULT_AND_CALLBACK(type, name, defaultValue) \
static type Get##name(Windows::UI::Xaml::DependencyObject ^ target) \
{ \
return safe_cast<type>(target->GetValue(s_##name##Property)); \
} \
static void Set##name(Windows::UI::Xaml::DependencyObject ^ target, type value) \
{ \
target->SetValue(s_##name##Property, value); \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ s_##name##Property; \
\
public: \
static property Windows::UI::Xaml::DependencyProperty ^ name##Property \
{ \
Windows::UI::Xaml::DependencyProperty ^ get() { \
assert(s_##name##Property); \
return s_##name##Property; \
} \
} \
\
private: \
static Windows::UI::Xaml::DependencyProperty ^ Initialize##name##Property() \
{ \
return Utils::RegisterDependencyPropertyAttachedWithCallback<DependencyPropertiesOwner, type>(L#name, defaultValue, &On##name##PropertyChangedImpl); \
} \
static void On##name##PropertyChangedImpl(Windows::UI::Xaml::DependencyObject ^ sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ args) \
{ \
On##name##PropertyChanged(sender, safe_cast<type>(args->OldValue), safe_cast<type>(args->NewValue)); \
} \
\
public:
// This goes into the cpp to initialize the static variable
#define DEPENDENCY_PROPERTY_INITIALIZATION(owner, name)\
Windows::UI::Xaml::DependencyProperty^ owner::s_##name##Property =\
owner::Initialize##name##Property();
#define DEPENDENCY_PROPERTY_INITIALIZATION(owner, name) Windows::UI::Xaml::DependencyProperty ^ owner::s_##name##Property = owner::Initialize##name##Property();
namespace CalculatorApp
{
template <typename T>
T from_cx(Platform::Object^ from)
T from_cx(Platform::Object ^ from)
{
T to{ nullptr };
winrt::check_hresult(reinterpret_cast<::IUnknown*>(from)->QueryInterface(winrt::guid_of<T>(),
reinterpret_cast<void**>(winrt::put_abi(to))));
winrt::check_hresult(reinterpret_cast<::IUnknown*>(from)->QueryInterface(winrt::guid_of<T>(), reinterpret_cast<void**>(winrt::put_abi(to))));
return to;
}

View File

@@ -3,81 +3,78 @@
#pragma once
namespace CalculatorApp { namespace Common
namespace CalculatorApp
{
public ref class ValidSelectedItemConverter sealed: public Windows::UI::Xaml::Data::IValueConverter
namespace Common
{
public:
ValidSelectedItemConverter()
{ }
private:
virtual Platform::Object^ Convert(
Platform::Object^ value,
Windows::UI::Xaml::Interop::TypeName /*targetType*/,
Platform::Object^ /*parameter*/,
Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert
public
ref class ValidSelectedItemConverter sealed : public Windows::UI::Xaml::Data::IValueConverter
{
// Pass through as we don't want to change the value from the source
return value;
}
virtual Platform::Object^ ConvertBack(
Platform::Object^ value,
Windows::UI::Xaml::Interop::TypeName /*targetType*/,
Platform::Object^ /*parameter*/,
Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack
{
if (value)
public:
ValidSelectedItemConverter()
{
}
private:
virtual Platform::Object
^ Convert(Platform::Object ^ value, Windows::UI::Xaml::Interop::TypeName /*targetType*/, Platform::Object ^ /*parameter*/,
Platform::String ^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert
{
// Pass through as we don't want to change the value from the source
return value;
}
// Stop the binding if the object is nullptr
return Windows::UI::Xaml::DependencyProperty::UnsetValue;
}
};
public ref class ValidSelectedIndexConverter sealed: public Windows::UI::Xaml::Data::IValueConverter
{
public:
ValidSelectedIndexConverter()
{ }
private:
virtual Platform::Object^ Convert(
Platform::Object^ value,
Windows::UI::Xaml::Interop::TypeName /*targetType*/,
Platform::Object^ /*parameter*/,
Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert
{
// Pass through as we don't want to change the value from the source
return value;
}
virtual Platform::Object^ ConvertBack(
Platform::Object^ value,
Windows::UI::Xaml::Interop::TypeName /*targetType*/,
Platform::Object^ /*parameter*/,
Platform::String^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack
{
// The value to be valid has to be a boxed int32 value
// extract that value and ensure it is valid, ie >= 0
if (value)
virtual Platform::Object
^ ConvertBack(Platform::Object ^ value, Windows::UI::Xaml::Interop::TypeName /*targetType*/, Platform::Object ^ /*parameter*/,
Platform::String ^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack
{
auto box = dynamic_cast<Windows::Foundation::IPropertyValue^>(value);
if (box && box->Type == Windows::Foundation::PropertyType::Int32)
if (value)
{
int index = box->GetInt32();
if (index >= 0)
return value;
}
// Stop the binding if the object is nullptr
return Windows::UI::Xaml::DependencyProperty::UnsetValue;
}
};
public
ref class ValidSelectedIndexConverter sealed : public Windows::UI::Xaml::Data::IValueConverter
{
public:
ValidSelectedIndexConverter()
{
}
private:
virtual Platform::Object
^ Convert(Platform::Object ^ value, Windows::UI::Xaml::Interop::TypeName /*targetType*/, Platform::Object ^ /*parameter*/,
Platform::String ^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert
{
// Pass through as we don't want to change the value from the source
return value;
}
virtual Platform::Object
^ ConvertBack(Platform::Object ^ value, Windows::UI::Xaml::Interop::TypeName /*targetType*/, Platform::Object ^ /*parameter*/,
Platform::String ^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack
{
// The value to be valid has to be a boxed int32 value
// extract that value and ensure it is valid, ie >= 0
if (value)
{
auto box = dynamic_cast<Windows::Foundation::IPropertyValue ^>(value);
if (box && box->Type == Windows::Foundation::PropertyType::Int32)
{
return value;
int index = box->GetInt32();
if (index >= 0)
{
return value;
}
}
}
// The value is not valid therefore stop the binding right here
return Windows::UI::Xaml::DependencyProperty::UnsetValue;
}
// The value is not valid therefore stop the binding right here
return Windows::UI::Xaml::DependencyProperty::UnsetValue;
}
};
}}
};
}
}