Skip to main content

Overview

The Currency Converter is a specialized component of the Unit Converter system that handles conversion between different currencies. It uses the ICurrencyConverterDataLoader interface to fetch live exchange rates from the web in production builds, but uses mock data in developer builds as documented in the project README.
Mock Data in Development BuildsWindows Calculator includes a currency converter feature that uses mock data in developer builds. The data that Microsoft uses for the currency converter (in the retail version) is not licensed for your use.The mock data references planets instead of countries and remains static regardless of selected inputs.

Currency Data Loading

The ICurrencyConverterDataLoader interface extends the standard IConverterDataLoader with currency-specific functionality. Header: ~/workspace/source/src/CalcManager/UnitConverter.h:188

Interface Methods

SetViewModelCallback

Registers a callback for currency-specific UI updates.
void SetViewModelCallback(
    const std::shared_ptr<IViewModelCurrencyCallback>& callback
);
callback
std::shared_ptr<IViewModelCurrencyCallback>
Callback interface for receiving currency symbols, ratios, timestamps, and network behavior updates

GetCurrencySymbols

Retrieves the currency symbols for two units.
std::pair<std::wstring, std::wstring> GetCurrencySymbols(
    _In_ const Unit& unit1,
    _In_ const Unit& unit2
);
unit1
const Unit&
First currency unit
unit2
const Unit&
Second currency unit
Returns: Pair of currency symbols (e.g., ”$”, ”€“)

GetCurrencyRatioEquality

Retrieves formatted strings showing the conversion ratio between two currencies.
std::pair<std::wstring, std::wstring> GetCurrencyRatioEquality(
    _In_ const Unit& unit1,
    _In_ const Unit& unit2
);
unit1
const Unit&
Source currency unit
unit2
const Unit&
Target currency unit
Returns: Pair of formatted ratio strings (normal and accessible versions) Example Output: ("1 USD = 0.85 EUR", "1 US Dollar equals 0.85 Euros")

GetCurrencyTimestamp

Retrieves the timestamp of when the currency data was last updated.
std::wstring GetCurrencyTimestamp();
Returns: Formatted timestamp string

TryLoadDataFromCacheAsync

Attempts to load currency data from local cache asynchronously.
std::future<bool> TryLoadDataFromCacheAsync();
Returns: Future resolving to true if cache data was loaded successfully, false otherwise

TryLoadDataFromWebAsync

Attempts to fetch fresh currency data from the web asynchronously.
std::future<bool> TryLoadDataFromWebAsync();
Returns: Future resolving to true if web data was fetched successfully, false otherwise
In developer builds, this method returns mock data instead of making actual network requests.

TryLoadDataFromWebOverrideAsync

Forces a refresh of currency data from the web, overriding any existing cached data.
std::future<bool> TryLoadDataFromWebOverrideAsync();
Returns: Future resolving to true if refresh succeeded, false otherwise See UnitConverter.h:200

Currency Callback Interface

The IViewModelCurrencyCallback interface allows the view model to receive currency-specific updates. Header: ~/workspace/source/src/CalcManager/UnitConverter.h:166

Callback Methods

CurrencyDataLoadFinished

Called when currency data loading completes.
virtual void CurrencyDataLoadFinished(bool didLoad) = 0;
didLoad
bool
true if data loaded successfully, false if loading failed

CurrencySymbolsCallback

Called when currency symbols are available.
virtual void CurrencySymbolsCallback(
    _In_ const std::wstring& fromSymbol,
    _In_ const std::wstring& toSymbol
) = 0;
fromSymbol
const std::wstring&
Currency symbol for the source unit (e.g., ”$”)
toSymbol
const std::wstring&
Currency symbol for the target unit (e.g., ”€“)

CurrencyRatiosCallback

Called with formatted currency conversion ratio strings.
virtual void CurrencyRatiosCallback(
    _In_ const std::wstring& ratioEquality,
    _In_ const std::wstring& accRatioEquality
) = 0;
ratioEquality
const std::wstring&
Standard formatted ratio string (e.g., “1 USD = 0.85 EUR”)
accRatioEquality
const std::wstring&
Accessibility-friendly ratio string (e.g., “1 US Dollar equals 0.85 Euros”)

CurrencyTimestampCallback

Called with the timestamp of the currency data.
virtual void CurrencyTimestampCallback(
    _In_ const std::wstring& timestamp,
    bool isWeekOldData
) = 0;
timestamp
const std::wstring&
Formatted timestamp string indicating when rates were last updated
isWeekOldData
bool
true if the data is more than a week old (may need refresh)

NetworkBehaviorChanged

Called when the network behavior or connectivity status changes.
virtual void NetworkBehaviorChanged(_In_ int newBehavior) = 0;
newBehavior
int
New network behavior code

Currency Data Structures

CurrencyStaticData

Static metadata for a currency.
struct CurrencyStaticData {
    std::wstring countryCode;
    std::wstring countryName;
    std::wstring currencyCode;
    std::wstring currencyName;
    std::wstring currencySymbol;
};
countryCode
std::wstring
ISO country code (e.g., “US”, “GB”)
countryName
std::wstring
Full country name (e.g., “United States”)In dev builds: Planet name instead (e.g., “Mars”, “Jupiter”)
currencyCode
std::wstring
ISO 4217 currency code (e.g., “USD”, “EUR”)
currencyName
std::wstring
Full currency name (e.g., “US Dollar”)
currencySymbol
std::wstring
Currency symbol (e.g., ”$”, ”€”, ”£”)
See UnitConverter.h:143

CurrencyRatio

Conversion ratio between two currencies.
struct CurrencyRatio {
    double ratio;
    std::wstring sourceCurrencyCode;
    std::wstring targetCurrencyCode;
};
ratio
double
Exchange rate from source to target currency
sourceCurrencyCode
std::wstring
ISO 4217 code for the source currency
targetCurrencyCode
std::wstring
ISO 4217 code for the target currency
See UnitConverter.h:152

Currency Unit Construction

Currency units have a specialized constructor that formats the display name differently:
Unit(
    int id,
    std::wstring_view currencyName,
    std::wstring_view countryName,
    std::wstring abbreviation,
    bool isRtlLanguage,
    bool isConversionSource,
    bool isConversionTarget
);
id
int
Unique identifier for the currency unit
currencyName
std::wstring_view
Name of the currency (e.g., “Dollar”)
countryName
std::wstring_view
Name of the country (e.g., “United States”)
In dev builds: Planet name (e.g., “Mars”)
abbreviation
std::wstring
Currency code (e.g., “USD”)
isRtlLanguage
bool
Whether the language is right-to-left (affects name formatting order)
isConversionSource
bool
Whether this is the source unit
isConversionTarget
bool
Whether this is the target unit
Name Formatting:
  • For LTR languages: "United States - Dollar"name = "United States - Dollar"
  • For RTL languages: "Dollar - United States"name = "Dollar - United States"
  • Accessible name uses space instead of dash: "United States Dollar"
See UnitConverter.h:32

Integration with UnitConverter

The UnitConverter class integrates currency conversion through several methods:

UpdateCurrencySymbols

Updates the currency symbols in the UI when units change.
void UpdateCurrencySymbols();
This method is called internally when SetCurrentUnitTypes() or SwitchActive() is invoked for currency categories. See UnitConverter.cpp:929

Currency-Specific Calculation Behavior

When converting currency values, the Calculate() method applies special formatting rules:
if (isCurrencyConverter) {
    // Currency uses MAXIMUMDIGITSALLOWED precision without scientific notation
    m_returnDisplay = RoundSignificantDigits(returnValue, MAXIMUMDIGITSALLOWED);
    TrimTrailingZeros(m_returnDisplay);
}
Currency conversions:
  • Always use maximum precision (15 significant digits)
  • Never use scientific notation
  • Trim trailing zeros for cleaner display
See UnitConverter.cpp:890

Usage Example

// Create specialized currency data loader
auto currencyLoader = std::make_shared<CurrencyDataLoader>();
auto standardLoader = std::make_shared<ConverterDataLoader>();

// Create converter with currency support
auto converter = std::make_shared<UnitConverter>(standardLoader, currencyLoader);
converter->Initialize();

// Set up currency callback
auto currencyCallback = std::make_shared<MyCurrencyCallback>();
converter->SetViewModelCurrencyCallback(currencyCallback);

// Select currency category
auto categories = converter->GetCategories();
for (const auto& cat : categories) {
    if (cat.name == L"Currency") {
        auto [units, fromUnit, toUnit] = converter->SetCurrentCategory(cat);
        
        // Find USD and EUR units
        Unit usdUnit, eurUnit;
        for (const auto& unit : units) {
            if (unit.abbreviation == L"USD") usdUnit = unit;
            if (unit.abbreviation == L"EUR") eurUnit = unit;
        }
        
        // Set up USD to EUR conversion
        converter->SetCurrentUnitTypes(usdUnit, eurUnit);
        
        // Input amount
        converter->SendCommand(Command::One);
        converter->SendCommand(Command::Zero);
        converter->SendCommand(Command::Zero);
        
        // Refresh rates from web
        auto refreshFuture = converter->RefreshCurrencyRatios();
        auto [success, timestamp] = refreshFuture.get();
        
        break;
    }
}

Mock Data Behavior

As documented in the README (~/workspace/source/README.md:64):
Developer Build Behavior
  • Currency data uses planets instead of countries
  • Exchange rates are static and do not change
  • Network calls return mock data immediately
  • Data “timestamp” reflects mock data generation, not real market data
This allows developers to:
  • Test currency conversion UI without requiring API keys
  • Work offline without network dependencies
  • Have consistent, predictable test data

Build docs developers (and LLMs) love