Windows 10 future version - February 2018 Update

This commit is contained in:
Raymond Chen 2018-02-07 17:00:05 -08:00
Родитель e9247157df c2ca5ee404
Коммит 64b49a8381
370 изменённых файлов: 3954 добавлений и 851 удалений

Просмотреть файл

@ -11,7 +11,7 @@
<Properties>
<DisplayName>360 Video Playback C++ Sample</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
<Logo>Assets\StoreLogo-sdk.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.15063.0" MaxVersionTested="10.0.16299.0"/>

Просмотреть файл

@ -66,12 +66,12 @@ namespace _360VideoPlayback.Common
// Initialize Direct2D resources.
var debugLevel = SharpDX.Direct2D1.DebugLevel.None;
//#if DEBUG
#if DEBUG
if (DirectXHelper.SdkLayersAvailable())
{
debugLevel = SharpDX.Direct2D1.DebugLevel.Information;
}
//#endif
#endif
// Initialize the Direct2D Factory.
d2dFactory = this.ToDispose(

Просмотреть файл

@ -11,7 +11,7 @@
<Properties>
<DisplayName>360 Video Playback C# Sample</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
<Logo>Assets\StoreLogo-sdk.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.15063.0" MaxVersionTested="10.0.16299.0"/>

Просмотреть файл

@ -64,7 +64,7 @@ For more information on network capabilities, see [How to set network capabiliti
**Client:** Windows 10
**Server:** Windows Server 2016 Technical Preview
**Server:** Windows Server 2016
**Phone:** Windows 10

Просмотреть файл

@ -8,8 +8,8 @@
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.16299.0</WindowsTargetPlatformMinVersion>
<WindowsTargetPlatformVersion>10.0.17069.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.17069.0</WindowsTargetPlatformMinVersion>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@ -163,6 +163,9 @@
<ClInclude Include="Scenario6_RecoverableErrors.xaml.h">
<DependentUpon>..\..\shared\Scenario6_RecoverableErrors.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="Scenario7_DownloadReordering.xaml.h">
<DependentUpon>..\..\shared\Scenario7_DownloadReordering.xaml</DependentUpon>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="..\..\..\..\SharedContent\xaml\App.xaml">
@ -177,6 +180,7 @@
<Page Include="..\..\shared\Scenario4_CompletionGroups.xaml" />
<Page Include="..\..\shared\Scenario5_RandomAccess.xaml" />
<Page Include="..\..\shared\Scenario6_RecoverableErrors.xaml" />
<Page Include="..\..\shared\Scenario7_DownloadReordering.xaml" />
<Page Include="..\..\..\..\SharedContent\xaml\Styles.xaml">
<Link>Styles\Styles.xaml</Link>
</Page>
@ -220,6 +224,9 @@
<ClCompile Include="Scenario6_RecoverableErrors.xaml.cpp">
<DependentUpon>..\..\shared\Scenario6_RecoverableErrors.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="Scenario7_DownloadReordering.xaml.cpp">
<DependentUpon>..\..\shared\Scenario7_DownloadReordering.xaml</DependentUpon>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Image Include="..\..\..\..\SharedContent\media\microsoft-sdk.png">

Просмотреть файл

@ -23,6 +23,7 @@
<ClCompile Include="Scenario4_CompletionGroups.xaml.cpp" />
<ClCompile Include="Scenario5_RandomAccess.xaml.cpp" />
<ClCompile Include="Scenario6_RecoverableErrors.xaml.cpp" />
<ClCompile Include="Scenario7_DownloadReordering.xaml.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
@ -35,6 +36,7 @@
<ClInclude Include="Scenario4_CompletionGroups.xaml.h" />
<ClInclude Include="Scenario5_RandomAccess.xaml.h" />
<ClInclude Include="Scenario6_RecoverableErrors.xaml.h" />
<ClInclude Include="Scenario7_DownloadReordering.xaml.h" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest" />
@ -50,6 +52,7 @@
<Page Include="..\..\shared\Scenario4_CompletionGroups.xaml" />
<Page Include="..\..\shared\Scenario5_RandomAccess.xaml" />
<Page Include="..\..\shared\Scenario6_RecoverableErrors.xaml" />
<Page Include="..\..\shared\Scenario7_DownloadReordering.xaml" />
</ItemGroup>
<ItemGroup>
<Image Include="..\..\..\..\SharedContent\media\microsoft-sdk.png">

Просмотреть файл

@ -20,7 +20,7 @@
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.10240.0" MaxVersionTested="10.0.16299.0" />
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17069.0" MaxVersionTested="10.0.17069.0" />
</Dependencies>
<Resources>

Просмотреть файл

@ -23,4 +23,5 @@ Platform::Array<Scenario>^ MainPage::scenariosInner = ref new Platform::Array<Sc
{ "Completion Groups", "SDKTemplate.Scenario4_CompletionGroups" },
{ "Random Access Downloads", "SDKTemplate.Scenario5_RandomAccess" },
{ "Recoverable Errors", "SDKTemplate.Scenario6_RecoverableErrors" },
{ "Download Reordering", "SDKTemplate.Scenario7_DownloadReordering" },
};

Просмотреть файл

@ -177,7 +177,7 @@ void Scenario1_Download::StartDownload(BackgroundTransferPriority priority)
// validating the URI is required since it was received from an untrusted source (user input).
// The URI is validated by calling TryGetUri() that will return 'false' for strings that are not valid URIs.
// Note that when enabling the text box users may provide URIs to machines on the intrAnet that require the
// "Home or Work Networking" capability.
// "Private Networks (Client and Server)" capability.
Uri^ source;
if (!rootPage->TryGetUri(serverAddressField->Text, &source))
{

Просмотреть файл

@ -96,7 +96,7 @@ void Scenario2_Upload::StartUpload_Click(Object^ sender, RoutedEventArgs^ e)
// Validating the URI is required since it was received from an untrusted source (user input).
// The URI is validated by calling TryGetUri() that will return 'false' for strings that are not valid URIs.
// Note that when enabling the text box users may provide URIs to machines on the intrAnet that require the
// "Home or Work Networking" capability.
// "Private Networks (Client and Server)" capability.
Uri^ uri;
if (!rootPage->TryGetUri(serverAddressField->Text, &uri))
{
@ -131,7 +131,7 @@ void Scenario2_Upload::StartMultipartUpload_Click(Object^ sender, RoutedEventArg
// Validating the URI is required (like TryGetUri) since it was received from an untrusted source (user input).
// The URI is validated by calling TryGetUri() that will return 'false' for strings that are not valid URIs.
// Note that when enabling the text box users may provide URIs to machines on the intrAnet that require the
// "Home or Work Networking" capability.
// "Private Networks (Client and Server)" capability.
Uri^ uri;
if (!rootPage->TryGetUri(serverAddressField->Text, &uri))
{

Просмотреть файл

@ -0,0 +1,295 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#include "pch.h"
#include "Scenario7_DownloadReordering.xaml.h"
using namespace SDKTemplate;
using namespace Concurrency;
using namespace Windows::Networking;
using namespace Windows::Networking::BackgroundTransfer;
using namespace Windows::Foundation::Collections;
using namespace Windows::Foundation;
using namespace Windows::Web;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Core;
using namespace Windows::Storage;
using namespace Platform::Collections;
using namespace Platform;
DownloadOperationItem::DownloadOperationItem(DownloadOperation^ download)
{
_download = download;
_percentComplete = 0;
_stateText = "Idle";
}
DownloadOperation^ DownloadOperationItem::download::get()
{
return _download;
}
int DownloadOperationItem::percentComplete::get()
{
return _percentComplete;
}
void DownloadOperationItem::percentComplete::set(int value)
{
if (_percentComplete != value)
{
_percentComplete = value;
PropertyChanged(this, ref new PropertyChangedEventArgs("percentComplete"));
}
}
String^ DownloadOperationItem::stateText::get()
{
return _stateText;
}
void DownloadOperationItem::stateText::set(String^ value)
{
if (_stateText != value)
{
_stateText = value;
PropertyChanged(this, ref new PropertyChangedEventArgs("stateText"));
}
}
Scenario7_DownloadReordering::Scenario7_DownloadReordering()
{
reorderGroup = BackgroundTransferGroup::CreateGroup("{7421B969-18D4-4532-B6BD-22BDABF71C08}");
reorderGroup->TransferBehavior = BackgroundTransferBehavior::Serialized;
_downloadCollection = ref new Vector<DownloadOperationItem^>();
DataContext = this;
InitializeComponent();
}
IObservableVector<DownloadOperationItem^>^ Scenario7_DownloadReordering::downloadCollection::get()
{
return _downloadCollection;
}
void Scenario7_DownloadReordering::OnNavigatedTo(NavigationEventArgs^ e)
{
rootPage = MainPage::Current;
CancelActiveDownloadsAsync().then([this](task<std::vector<DownloadOperation^>> previousTask)
{
try
{
previousTask.get();
}
catch (Exception^ ex)
{
if (!IsWebException("Discovery error", ex))
{
throw;
}
}
});
}
task<std::vector<DownloadOperation^>> Scenario7_DownloadReordering::CancelActiveDownloadsAsync()
{
// Only the downloads that belong to the transfer group used by this sample scenario will be
// canceled.
return create_task(BackgroundDownloader::GetCurrentDownloadsForTransferGroupAsync(reorderGroup))
.then([this](IVectorView<DownloadOperation^>^ downloads)
{
std::vector<task<DownloadOperation^>> tasks;
// If previous instances of this scenario started transfers that haven't completed yet,
// cancel them now so that we can start this scenario cleanly.
if (downloads->Size > 0)
{
cancellation_token_source cancellationToken;
for (DownloadOperation^ download : downloads) {
tasks.push_back(create_task(download->AttachAsync(), cancellationToken.get_token()));
}
cancellationToken.cancel();
}
return when_all(tasks.begin(), tasks.end());
});
}
void Scenario7_DownloadReordering::StartDownload_Click(Object^ sender, RoutedEventArgs^ e)
{
Button^ startButton = safe_cast<Button^>(sender);
startButton->IsEnabled = false;
// Create and start downloads.
RunDownloadsAsync().then([this, startButton]()
{
// After all downloads are complete, let the user start new ones again.
startButton->IsEnabled = true;
}, task_continuation_context::use_current());
}
void Scenario7_DownloadReordering::MakeCurrent_Click(Object^ sender, RoutedEventArgs e)
{
Button^ button = safe_cast<Button^>(sender);
DownloadOperationItem^ item = safe_cast<DownloadOperationItem^>(button->DataContext);
// Make the selected operation current.
item->download->MakeCurrentInTransferGroup();
}
task<void> Scenario7_DownloadReordering::RunDownloadsAsync()
{
// Create a downloader and associate all its downloads with the transfer group used for this
// scenario.
BackgroundDownloader^ downloader = ref new BackgroundDownloader();
downloader->TransferGroup = reorderGroup;
// Validating the URI is required since it was received from an untrusted source (user input).
// The URI is validated by calling rootPage->TryGetUri() that will return 'false' for strings
// that are not valid URIs.
// Note that when enabling the text box users may provide URIs to machines on the intranet that
// require the "Private Networks (Client and Server)" capability.
String^ remoteAddress = StringTrimmer::Trim(remoteAddressField->Text);
Uri^ tmpUri;
if (!rootPage->TryGetUri(remoteAddress, &tmpUri))
{
return task_from_result();
}
String^ fileName = StringTrimmer::Trim(fileNameField->Text);
if (fileName->IsEmpty())
{
rootPage->NotifyUser("A local file name is required.", NotifyType::ErrorMessage);
return task_from_result();
}
// Try to create some downloads.
std::vector<task<DownloadOperation^>> createDownloadTasks;
for (int i = 0; i < NumDownloads; i++)
{
String^ currRemoteAddress = remoteAddress + "?id=" + i.ToString();
String^ currFileName = i.ToString() + "." + fileName;
createDownloadTasks.push_back(CreateDownloadAsync(downloader, currRemoteAddress, currFileName));
}
return when_all(createDownloadTasks.begin(), createDownloadTasks.end())
.then([this](std::vector<DownloadOperation^> downloads)
{
// Once all downloads have been created, start them.
_downloadCollection->Clear();
std::vector<task<void>> downloadTasks;
for (DownloadOperation^ download : downloads)
{
DownloadOperationItem^ item = ref new DownloadOperationItem(download);
downloadTasks.push_back(DownloadAsync(item));
_downloadCollection->Append(item);
}
return when_all(downloadTasks.begin(), downloadTasks.end());
});
}
task<DownloadOperation^> Scenario7_DownloadReordering::CreateDownloadAsync(
BackgroundDownloader^ downloader,
String^ remoteAddress,
String^ fileName)
{
return create_task(KnownFolders::PicturesLibrary->CreateFileAsync(
fileName,
CreationCollisionOption::GenerateUniqueName))
.then([this, downloader, remoteAddress](StorageFile^ destinationFile)
{
Uri^ source = ref new Uri(remoteAddress);
return downloader->CreateDownload(source, destinationFile);
});
}
task<void> Scenario7_DownloadReordering::DownloadAsync(DownloadOperationItem^ item)
{
IAsyncOperationWithProgress<DownloadOperation^, DownloadOperation^>^ async = item->download->StartAsync();
async->Progress = ref new AsyncOperationProgressHandler<DownloadOperation^, DownloadOperation^>(
[this, item](
IAsyncOperationWithProgress<DownloadOperation^, DownloadOperation^>^ operation,
DownloadOperation^ download)
{
DownloadProgress(item);
});
return create_task(async).then([this, item](DownloadOperation^ download)
{
item->stateText = item->download->Progress.Status.ToString();
rootPage->NotifyUser(
"Downloading " + item->download->ResultFile->Name + " completed.",
NotifyType::StatusMessage);
}).then([this, item](task<void> previousTask)
{
try
{
previousTask.get();
}
catch (Exception^ ex)
{
// Ignore canceled downloads since they are not displayed.
if (item->download->Progress.Status != BackgroundTransferStatus::Canceled)
{
// Ensure that we reach 100% even for errors.
item->percentComplete = 100;
item->stateText = item->download->Progress.Status.ToString();
if (!IsWebException("Execution error", ex, item->download))
{
throw;
}
}
}
});
}
void Scenario7_DownloadReordering::DownloadProgress(DownloadOperationItem^ item)
{
BackgroundDownloadProgress currentProgress = item->download->Progress;
BackgroundTransferStatus status = currentProgress.Status;
int percentComplete = 0;
if (currentProgress.TotalBytesToReceive > 0)
{
percentComplete = (int)((currentProgress.BytesReceived * 100) / currentProgress.TotalBytesToReceive);
}
Dispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new DispatchedHandler(
[this, item, status, percentComplete]()
{
item->stateText = status.ToString();
item->percentComplete = percentComplete;
}));
}
bool Scenario7_DownloadReordering::IsWebException(String^ title, Exception^ ex, DownloadOperation^ download)
{
WebErrorStatus error = BackgroundTransferError::GetStatus(ex->HResult);
bool result = (error != WebErrorStatus::Unknown);
String^ message = result ? error.ToString() : ex->Message;
if (download == nullptr)
{
rootPage->NotifyUser(title + ": " + message, NotifyType::ErrorMessage);
}
else
{
rootPage->NotifyUser(download->ResultFile->Name + " - " + title + ": " + message, NotifyType::ErrorMessage);
}
return result;
}

Просмотреть файл

@ -0,0 +1,87 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#pragma once
#include "pch.h"
#include "Scenario7_DownloadReordering.g.h"
#include "MainPage.xaml.h"
namespace SDKTemplate
{
// Class for each download and its row in the UI.
public ref class DownloadOperationItem sealed : Windows::UI::Xaml::Data::INotifyPropertyChanged
{
public:
DownloadOperationItem(Windows::Networking::BackgroundTransfer::DownloadOperation^ download);
virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;
property Windows::Networking::BackgroundTransfer::DownloadOperation^ download
{
Windows::Networking::BackgroundTransfer::DownloadOperation^ get();
}
property int percentComplete
{
int get();
void set(int value);
}
property Platform::String^ stateText
{
Platform::String^ get();
void set(Platform::String^ value);
}
private:
Windows::Networking::BackgroundTransfer::DownloadOperation^ _download;
int _percentComplete;
Platform::String^ _stateText;
};
[Windows::Foundation::Metadata::WebHostHidden]
public ref class Scenario7_DownloadReordering sealed
{
public:
Scenario7_DownloadReordering();
property Windows::Foundation::Collections::IObservableVector<DownloadOperationItem^>^ downloadCollection
{
Windows::Foundation::Collections::IObservableVector<DownloadOperationItem^>^ get();
}
protected:
virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
private:
Concurrency::task<std::vector<Windows::Networking::BackgroundTransfer::DownloadOperation^>>
CancelActiveDownloadsAsync();
void StartDownload_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void MakeCurrent_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs e);
Concurrency::task<void> RunDownloadsAsync();
Concurrency::task<Windows::Networking::BackgroundTransfer::DownloadOperation^> CreateDownloadAsync(
Windows::Networking::BackgroundTransfer::BackgroundDownloader^ downloader,
Platform::String^ remoteAddress,
Platform::String^ fileName);
Concurrency::task<void> DownloadAsync(DownloadOperationItem^ item);
void DownloadProgress(DownloadOperationItem^ item);
bool Scenario7_DownloadReordering::IsWebException(
Platform::String^ title,
Platform::Exception^ ex,
Windows::Networking::BackgroundTransfer::DownloadOperation^ download = nullptr);
const int NumDownloads = 5;
MainPage^ rootPage;
Windows::Networking::BackgroundTransfer::BackgroundTransferGroup^ reorderGroup;
Windows::Foundation::Collections::IObservableVector<DownloadOperationItem^>^ _downloadCollection;
};
}

Просмотреть файл

@ -36,8 +36,8 @@
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.16299.0</WindowsTargetPlatformMinVersion>
<WindowsTargetPlatformVersion>10.0.17069.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.17069.0</WindowsTargetPlatformMinVersion>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

Просмотреть файл

@ -11,8 +11,8 @@
<AssemblyName>BackgroundTransfer</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
<TargetPlatformVersion>10.0.17069.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17069.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
<FileAlignment>512</FileAlignment>
@ -121,6 +121,9 @@
<Compile Include="Scenario6_RecoverableErrors.xaml.cs">
<DependentUpon>Scenario6_RecoverableErrors.xaml</DependentUpon>
</Compile>
<Compile Include="Scenario7_DownloadReordering.xaml.cs">
<DependentUpon>Scenario7_DownloadReordering.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
@ -168,6 +171,11 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="..\..\shared\Scenario7_DownloadReordering.xaml">
<Link>Scenario7_DownloadReordering.xaml</Link>
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="..\..\..\..\SharedContent\xaml\Styles.xaml">
<Link>Styles\Styles.xaml</Link>
<Generator>MSBuild:Compile</Generator>

Просмотреть файл

@ -20,7 +20,7 @@
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.16299.0" MaxVersionTested="10.0.16299.0" />
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17069.0" MaxVersionTested="10.0.17069.0" />
</Dependencies>
<Resources>

Просмотреть файл

@ -26,7 +26,8 @@ namespace SDKTemplate
new Scenario() { Title="Completion Notifications", ClassType=typeof(Scenario3_Notifications)},
new Scenario() { Title="Completion Groups", ClassType=typeof(Scenario4_CompletionGroups)},
new Scenario() { Title="Random Access Downloads", ClassType=typeof(Scenario5_RandomAccess)},
new Scenario() { Title="Recoverable Errors", ClassType=typeof(Scenario6_RecoverableErrors)}
new Scenario() { Title="Recoverable Errors", ClassType=typeof(Scenario6_RecoverableErrors)},
new Scenario() { Title="Download Reordering", ClassType=typeof(Scenario7_DownloadReordering)},
};
}

Просмотреть файл

@ -117,7 +117,7 @@ namespace SDKTemplate
// Validating the URI is required since it was received from an untrusted source (user input).
// The URI is validated by calling Uri.TryCreate() that will return 'false' for strings that are not valid URIs.
// Note that when enabling the text box users may provide URIs to machines on the intrAnet that require
// the "Home or Work Networking" capability.
// the "Private Networks (Client and Server)" capability.
Uri source;
if (!Uri.TryCreate(serverAddressField.Text.Trim(), UriKind.Absolute, out source))
{

Просмотреть файл

@ -115,7 +115,7 @@ namespace SDKTemplate
// Validating the URI is required since it was received from an untrusted source (user input).
// The URI is validated by calling Uri.TryCreate() that will return 'false' for strings that are not valid URIs.
// Note that when enabling the text box users may provide URIs to machines on the intrAnet that require
// the "Home or Work Networking" capability.
// the "Private Networks (Client and Server)" capability.
Uri uri;
if (!Uri.TryCreate(serverAddressField.Text.Trim(), UriKind.Absolute, out uri))
{
@ -163,7 +163,7 @@ namespace SDKTemplate
// box validating the URI is required since it was received from an untrusted source (user input).
// The URI is validated by calling Uri.TryCreate() that will return 'false' for strings that are not valid URIs.
// Note that when enabling the text box users may provide URIs to machines on the intrAnet that require
// the "Home or Work Networking" capability.
// the "Private Networks (Client and Server)" capability.
Uri uri;
if (!Uri.TryCreate(serverAddressField.Text.Trim(), UriKind.Absolute, out uri))
{

Просмотреть файл

@ -188,7 +188,7 @@ namespace SDKTemplate
// Validating the URI is required since it was received from an untrusted source (user input).
// The URI is validated by calling Uri.TryCreate() that will return 'false' for strings that are not valid URIs.
// Note that when enabling the text box users may provide URIs to machines on the intrAnet that require
// the "Home or Work Networking" capability.
// the "Private Networks (Client and Server)" capability.
if (!Uri.TryCreate(serverAddressField.Text.Trim(), UriKind.Absolute, out baseUri))
{
rootPage.NotifyUser("Invalid URI.", NotifyType.ErrorMessage);

Просмотреть файл

@ -0,0 +1,321 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Windows.Networking.BackgroundTransfer;
using Windows.Storage;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Windows.Web;
namespace SDKTemplate
{
// Class for each download and its row in the UI.
public class DownloadOperationItem : INotifyPropertyChanged
{
public DownloadOperationItem(DownloadOperation download)
{
_download = download;
_percentComplete = 0;
_stateText = "Idle";
}
public event PropertyChangedEventHandler PropertyChanged;
public DownloadOperation download
{
get
{
return _download;
}
}
public int percentComplete
{
get
{
return _percentComplete;
}
set
{
_percentComplete = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("percentComplete"));
}
}
}
public string stateText
{
get
{
return _stateText;
}
set
{
_stateText = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("stateText"));
}
}
}
private DownloadOperation _download;
private int _percentComplete;
private string _stateText;
}
public sealed partial class Scenario7_DownloadReordering : Page
{
private const int NumDownloads = 5;
private MainPage rootPage;
private BackgroundTransferGroup reorderGroup;
public ObservableCollection<DownloadOperationItem> downloadCollection { get; } =
new ObservableCollection<DownloadOperationItem>();
public Scenario7_DownloadReordering()
{
reorderGroup = BackgroundTransferGroup.CreateGroup("{7421B969-18D4-4532-B6BD-22BDABF71C08}");
reorderGroup.TransferBehavior = BackgroundTransferBehavior.Serialized;
this.DataContext = this;
this.InitializeComponent();
}
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
rootPage = MainPage.Current;
await CancelActiveDownloadsAsync();
}
private async Task CancelActiveDownloadsAsync()
{
// Only the downloads that belong to the transfer group used by this sample scenario
// will be canceled.
IReadOnlyList<DownloadOperation> downloads = null;
try
{
downloads = await BackgroundDownloader.GetCurrentDownloadsForTransferGroupAsync(reorderGroup);
}
catch (Exception ex)
{
if (!IsWebException("Discovery error", ex))
{
throw;
}
return;
}
// If previous instances of this scenario started transfers that haven't completed yet,
// cancel them now so that we can start this scenario cleanly.
if (downloads.Count > 0)
{
CancellationTokenSource cancellationToken = new CancellationTokenSource();
cancellationToken.Cancel();
Task[] tasks = new Task[downloads.Count];
for (int i = 0; i < downloads.Count; i++)
{
tasks[i] = downloads[i].AttachAsync().AsTask(cancellationToken.Token);
}
// Cancel each download and ignore the cancellation exception.
try
{
await Task.WhenAll(tasks);
}
catch (TaskCanceledException)
{
}
}
}
private async void StartDownload_Click(object sender, RoutedEventArgs e)
{
startDownloadButton.IsEnabled = false;
// Create and start downloads.
await RunDownloadsAsync();
// After all downloads are complete, let the user start new ones again.
startDownloadButton.IsEnabled = true;
}
private void MakeCurrent_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
DownloadOperationItem item = button.DataContext as DownloadOperationItem;
// Make the selected operation current.
item.download.MakeCurrentInTransferGroup();
}
private async Task RunDownloadsAsync()
{
// Create a downloader and associate all its downloads with the transfer group used for
// this scenario.
BackgroundDownloader downloader = new BackgroundDownloader();
downloader.TransferGroup = reorderGroup;
// Validating the URI is required since it was received from an untrusted source (user
// input).
// The URI is validated by calling Uri.TryCreate() that will return 'false' for strings
// that are not valid URIs.
// Note that when enabling the text box users may provide URIs to machines on the
// intranet that require the "Private Networks (Client and Server)" capability.
string remoteAddress = remoteAddressField.Text.Trim();
Uri tmpUri;
if (!Uri.TryCreate(remoteAddress, UriKind.Absolute, out tmpUri))
{
rootPage.NotifyUser("Invalid URI.", NotifyType.ErrorMessage);
return;
}
string fileName = fileNameField.Text.Trim();
if (string.IsNullOrWhiteSpace(fileName))
{
rootPage.NotifyUser("A local file name is required.", NotifyType.ErrorMessage);
return;
}
// Try to create some downloads.
DownloadOperation[] downloads = new DownloadOperation[NumDownloads];
try
{
for (int i = 0; i < NumDownloads; i++)
{
string currRemoteAddress = $"{remoteAddress}?id={i}";
string currFileName = $"{i}.{fileName}";
downloads[i] = await CreateDownload(downloader, currRemoteAddress, currFileName);
}
}
catch (FileNotFoundException ex)
{
rootPage.NotifyUser($"Error while creating file: {ex.Message}", NotifyType.ErrorMessage);
return;
}
// Once all downloads have been created, start them.
Task[] downloadTasks = new Task[downloads.Length];
downloadCollection.Clear();
for (int i = 0; i < downloads.Length; i++)
{
DownloadOperationItem item = new DownloadOperationItem(downloads[i]);
downloadTasks[i] = DownloadAsync(item);
downloadCollection.Add(item);
}
await Task.WhenAll(downloadTasks);
}
private async Task<DownloadOperation> CreateDownload(
BackgroundDownloader downloader,
string remoteAddress,
string fileName)
{
Uri source = new Uri(remoteAddress);
StorageFile destinationFile;
try
{
destinationFile = await KnownFolders.PicturesLibrary.CreateFileAsync(
fileName,
CreationCollisionOption.GenerateUniqueName);
}
catch (FileNotFoundException ex)
{
rootPage.NotifyUser($"Error while creating file: {ex.Message}", NotifyType.ErrorMessage);
throw;
}
return downloader.CreateDownload(source, destinationFile);
}
private async Task DownloadAsync(DownloadOperationItem item)
{
Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(
(operation) => DownloadProgress(item));
try
{
await item.download.StartAsync().AsTask(progressCallback);
item.stateText = item.download.Progress.Status.ToString();
rootPage.NotifyUser(
$"Downloading {item.download.ResultFile.Name} completed.",
NotifyType.StatusMessage);
}
catch (Exception ex)
{
// Ignore canceled downloads since they are not displayed.
if (item.download.Progress.Status != BackgroundTransferStatus.Canceled)
{
// Ensure that we reach 100% even for errors.
item.percentComplete = 100;
item.stateText = item.download.Progress.Status.ToString();
if (!IsWebException("Execution error", ex, item.download))
{
throw;
}
}
}
}
private void DownloadProgress(DownloadOperationItem item)
{
BackgroundDownloadProgress currentProgress = item.download.Progress;
BackgroundTransferStatus status = currentProgress.Status;
int percentComplete = 0;
if (currentProgress.TotalBytesToReceive > 0)
{
percentComplete = (int)((currentProgress.BytesReceived * 100) / currentProgress.TotalBytesToReceive);
}
var ignore = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
item.stateText = status.ToString();
item.percentComplete = percentComplete;
});
}
private bool IsWebException(string title, Exception ex, DownloadOperation download = null)
{
WebErrorStatus error = BackgroundTransferError.GetStatus(ex.HResult);
bool result = (error != WebErrorStatus.Unknown);
string message = result ? error.ToString() : ex.Message;
if (download == null)
{
rootPage.NotifyUser($"{title}: {message}", NotifyType.ErrorMessage);
}
else
{
rootPage.NotifyUser($"{download.ResultFile.Name} - {title}: {message}", NotifyType.ErrorMessage);
}
return result;
}
}
}

Просмотреть файл

@ -11,8 +11,8 @@
<AssemblyName>Tasks</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
<TargetPlatformVersion>10.0.17069.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17069.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
<FileAlignment>512</FileAlignment>

Просмотреть файл

@ -45,8 +45,8 @@
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" />
<PropertyGroup>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
<TargetPlatformVersion>10.0.17069.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17069.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>$(VersionNumberMajor).$(VersionNumberMinor)</MinimumVisualStudioVersion>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
@ -87,6 +87,7 @@
<Content Include="html\scenario4_CompletionGroups.html" />
<Content Include="html\scenario5_RandomAccess.html" />
<Content Include="html\scenario6_RecoverableErrors.html" />
<Content Include="html\scenario7_DownloadReordering.html" />
<Content Include="js\completionGroupBackgroundTask.js" />
<Content Include="js\sample-configuration.js" />
<Content Include="js\scenario1_Download.js" />
@ -95,6 +96,7 @@
<Content Include="js\scenario4_CompletionGroups.js" />
<Content Include="js\scenario5_RandomAccess.js" />
<Content Include="js\scenario6_RecoverableErrors.js" />
<Content Include="js\scenario7_DownloadReordering.js" />
<Content Include="..\..\..\SharedContent\js\Microsoft.WinJS\css\ui-dark.css">
<Link>Microsoft.WinJS.4.0\css\ui-dark.css</Link>
</Content>

Просмотреть файл

@ -0,0 +1,65 @@
<!--
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
-->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="/js/scenario7_DownloadReordering.js"></script>
</head>
<body class="win-type-body">
<h2 id="sampleHeader" class="win-type-subheader">Description:</h2>
<div id="scenarioDescription">Download reordering</div>
<p>
Transfers which belong to the same transfer group can be reordered after they have been started.
</p>
<p>
<label for="remoteAddressField">Remote address: </label>
<input type="text" class="win-textbox" id="remoteAddressField" value="http://localhost/BackgroundTransferSample/download.aspx" />
</p>
<p>
<label for="fileNameField">Local file name: </label>
<input type="text" class="win-textbox" id="fileNameField" value="DownloadReordering.txt" />
</p>
<p>
<button class="win-button" id="startDownloadButton">Start Download</button>
</p>
<p>
Select a pending transfer to reorder the downloads.
</p>
<p>
<button class="win-button" id="makeCurrentButton0" disabled>Make Current</button>
<input id="percentCompleteInput0" type="range" min="0" max="100" step="1" value="0" />
<span id="stateTextSpan0">idle</span>
</p>
<p>
<button class="win-button" id="makeCurrentButton1" disabled>Make Current</button>
<input id="percentCompleteInput1" type="range" min="0" max="100" step="1" value="0" />
<span id="stateTextSpan1">idle</span>
</p>
<p>
<button class="win-button" id="makeCurrentButton2" disabled>Make Current</button>
<input id="percentCompleteInput2" type="range" min="0" max="100" step="1" value="0" />
<span id="stateTextSpan2">idle</span>
</p>
<p>
<button class="win-button" id="makeCurrentButton3" disabled>Make Current</button>
<input id="percentCompleteInput3" type="range" min="0" max="100" step="1" value="0" />
<span id="stateTextSpan3">idle</span>
</p>
<p>
<button class="win-button" id="makeCurrentButton4" disabled>Make Current</button>
<input id="percentCompleteInput4" type="range" min="0" max="100" step="1" value="0" />
<span id="stateTextSpan4">idle</span>
</p>
</body>
</html>

Просмотреть файл

@ -19,7 +19,8 @@
{ url: "/html/scenario3_Notifications.html", title: "Completion Notifications" },
{ url: "/html/scenario4_CompletionGroups.html", title: "Completion Groups" },
{ url: "/html/scenario5_RandomAccess.html", title: "Random Access" },
{ url: "/html/scenario6_RecoverableErrors.html", title: "Recoverable Errors" }
{ url: "/html/scenario6_RecoverableErrors.html", title: "Recoverable Errors" },
{ url: "/html/scenario7_DownloadReordering.html", title: "Download Reordering" }
];
// Look up the name for an enumeration member.

Просмотреть файл

@ -44,32 +44,6 @@
// Global array used to persist operations.
var downloadOperations = [];
function backgroundTransferStatusToString(transferStatus) {
switch (transferStatus)
{
case BackgroundTransfer.BackgroundTransferStatus.idle:
return "Idle";
case BackgroundTransfer.BackgroundTransferStatus.running:
return "Running";
case BackgroundTransfer.BackgroundTransferStatus.pausedByApplication:
return "PausedByApplication";
case BackgroundTransfer.BackgroundTransferStatus.pausedCostedNetwork:
return "PausedCostedNetwork";
case BackgroundTransfer.BackgroundTransferStatus.pausedNoNetwork:
return "PausedNoNetwork";
case BackgroundTransfer.BackgroundTransferStatus.completed:
return "Completed";
case BackgroundTransfer.BackgroundTransferStatus.canceled:
return "Canceled";
case BackgroundTransfer.BackgroundTransferStatus.error:
return "Error";
case BackgroundTransfer.BackgroundTransferStatus.pausedSystemPolicy:
return "PausedSystemPolicy";
default:
return "Unknown";
}
}
// Class associated with each download.
function DownloadOperation() {
var download = null;
@ -100,7 +74,8 @@
this.load = function (loadedDownload) {
download = loadedDownload;
printLog("Discovered background download: " + download.guid + ", Status: " +
backgroundTransferStatusToString(download.progress.status) + "<br/>");
SdkSample.lookupEnumName(BackgroundTransfer.BackgroundTransferStatus, download.progress.status) +
"<br/>");
promise = download.attachAsync().then(complete, error, progress);
};
@ -128,7 +103,8 @@
printLog("Resumed: " + download.guid + "<br/>");
} else {
printLog("Skipped: " + download.guid + ", Status: " +
backgroundTransferStatusToString(currentProgress.status) + "<br/>");
SdkSample.lookupEnumName(BackgroundTransfer.BackgroundTransferStatus, currentProgress.status) +
"<br/>");
}
}
};
@ -146,7 +122,8 @@
printLog("Paused: " + download.guid + "<br/>");
} else {
printLog("Skipped: " + download.guid + ", Status: " +
backgroundTransferStatusToString(currentProgress.status) + "<br/>");
SdkSample.lookupEnumName(BackgroundTransfer.BackgroundTransferStatus, currentProgress.status) +
"<br/>");
}
}
};
@ -173,7 +150,8 @@
var currentProgress = download.progress;
printLog("Progress: " + download.guid + ", Status: " +
backgroundTransferStatusToString(currentProgress.status) + "<br/>");
SdkSample.lookupEnumName(BackgroundTransfer.BackgroundTransferStatus, currentProgress.status) +
"<br/>");
var percent = 100;
if (currentProgress.totalBytesToReceive > 0) {

Просмотреть файл

@ -61,31 +61,6 @@
var maxUploadFileSize = 100 * 1024 * 1024; // 100 MB (arbitrary limit chosen for this sample)
function backgroundTransferStatusToString(transferStatus) {
switch (transferStatus) {
case BackgroundTransfer.BackgroundTransferStatus.idle:
return "Idle";
case BackgroundTransfer.BackgroundTransferStatus.running:
return "Running";
case BackgroundTransfer.BackgroundTransferStatus.pausedByApplication:
return "PausedByApplication";
case BackgroundTransfer.BackgroundTransferStatus.pausedCostedNetwork:
return "PausedCostedNetwork";
case BackgroundTransfer.BackgroundTransferStatus.pausedNoNetwork:
return "PausedNoNetwork";
case BackgroundTransfer.BackgroundTransferStatus.completed:
return "Completed";
case BackgroundTransfer.BackgroundTransferStatus.canceled:
return "Canceled";
case BackgroundTransfer.BackgroundTransferStatus.error:
return "Error";
case BackgroundTransfer.BackgroundTransferStatus.pausedSystemPolicy:
return "PausedSystemPolicy";
default:
return "Unknown";
}
}
// Class associated with each upload.
function UploadOperation() {
var upload = null;
@ -132,7 +107,8 @@
this.load = function (loadedUpload) {
upload = loadedUpload;
printLog("Discovered background upload: " + upload.guid + " , Status: " +
backgroundTransferStatusToString(upload.progress.status) + "<br/>");
SdkSample.lookupEnumName(BackgroundTransfer.BackgroundTransferStatus, upload.progress.status) +
"<br/>");
promise = upload.attachAsync().then(complete, error, progress);
};
@ -169,7 +145,8 @@
var currentProgress = upload.progress;
printLog("Progress: " + upload.guid + ", Status: " +
backgroundTransferStatusToString(currentProgress.status) + "<br/>");
SdkSample.lookupEnumName(BackgroundTransfer.BackgroundTransferStatus, currentProgress.status) +
"<br/>");
var percent = 100;
if (currentProgress.totalBytesToSend > 0) {

Просмотреть файл

@ -0,0 +1,220 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
(function () {
"use strict";
var BackgroundTransfer = Windows.Networking.BackgroundTransfer;
// Class for each download and its row in the UI.
function DownloadCollectionItem(i) {
var makeCurrentButton = document.getElementById("makeCurrentButton" + i);
var percentCompleteInput = document.getElementById("percentCompleteInput" + i);
var stateTextSpan = document.getElementById("stateTextSpan" + i);
var download = null;
this.startAsync = function (dl) {
download = dl;
makeCurrentButton.addEventListener("click", makeCurrent_click);
makeCurrentButton.disabled = false;
percentCompleteInput.value = 0;
stateTextSpan.innerText = "idle";
return download.startAsync().then(complete, error, progress);
}
this.reset = function () {
makeCurrentButton.disabled = true;
download = null;
}
function makeCurrent_click() {
// Make the selected operation current.
download.makeCurrentInTransferGroup();
}
function complete() {
stateTextSpan.innerText = SdkSample.lookupEnumName(
BackgroundTransfer.BackgroundTransferStatus,
download.progress.status);
WinJS.log(`Downloading ${download.resultFile.name} completed.`, "sample", "status");
};
function error(err) {
// Ignore canceled downloads since they are not displayed.
if (download.progress.status != BackgroundTransfer.BackgroundTransferStatus.canceled) {
// Ensure that we reach 100% even for errors.
percentCompleteInput.value = 100;
stateTextSpan.innerText = SdkSample.lookupEnumName(
BackgroundTransfer.BackgroundTransferStatus,
download.progress.status);
if (!isWebException("Execution error", err, download)) {
return WinJS.Promise.wrapError(err);
}
}
}
function progress() {
var currentProgress = download.progress;
var percentComplete = 0;
if (currentProgress.totalBytesToReceive > 0) {
percentComplete = Math.floor(
(currentProgress.bytesReceived * 100) / currentProgress.totalBytesToReceive);
}
percentCompleteInput.value = percentComplete;
stateTextSpan.innerText = SdkSample.lookupEnumName(
BackgroundTransfer.BackgroundTransferStatus,
currentProgress.status);
}
}
const NumDownloads = 5;
var remoteAddressField;
var fileNameField;
var startDownloadButton;
var reorderGroup;
var downloadCollection;
var page = WinJS.UI.Pages.define("/html/scenario7_DownloadReordering.html", {
ready: function (element, options) {
remoteAddressField = document.getElementById("remoteAddressField");
fileNameField = document.getElementById("fileNameField");
startDownloadButton = document.getElementById("startDownloadButton");
startDownloadButton.addEventListener("click", startDownload_click);
reorderGroup = BackgroundTransfer.BackgroundTransferGroup.createGroup(
"{7421B969-18D4-4532-B6BD-22BDABF71C08}");
reorderGroup.transferBehavior = BackgroundTransfer.BackgroundTransferBehavior.serialized;
downloadCollection = [];
for (var i = 0; i < NumDownloads; i++) {
downloadCollection.push(new DownloadCollectionItem(i));
}
cancelActiveDownloadsAsync().done();
}
});
function cancelActiveDownloadsAsync() {
// Only the downloads that belong to the transfer group used by this sample scenario will be
// canceled.
return BackgroundTransfer.BackgroundDownloader.getCurrentDownloadsForTransferGroupAsync(reorderGroup)
.then(function (downloads) {
// If previous sample instances/scenarios started transfers that haven't completed yet,
// cancel them now so that we can start this scenario cleanly.
if (downloads.length > 0) {
var promises = downloads.map(function (download) {
// Cancel each download and ignore the cancellation exception.
var downloadPromise = download.attachAsync();
downloadPromise.cancel();
return downloadPromise.then(null, function (err) {
if (download.progress.status != BackgroundTransfer.BackgroundTransferStatus.canceled) {
if (!isWebException("Discovery error", err, null)) {
return WinJS.Promise.wrapError(err);
}
}
});
})
return WinJS.Promise.join(promises);
}
});
}
function startDownload_click() {
startDownloadButton.disabled = true;
// Create and start downloads.
runDownloadAsync(function () {
// After all downloads are complete, disable the downloads and let the user start new
// ones again.
downloadCollection.forEach(function (downloadCollectionItem) {
downloadCollectionItem.reset();
});
startDownloadButton.disabled = false;
});
}
function runDownloadAsync(done_callback) {
// Create a downloader and associate all its downloads with the transfer group used for this
// scenario.
var downloader = new BackgroundTransfer.BackgroundDownloader();
downloader.transferGroup = reorderGroup;
// Validating the URI is required since it was received from an untrusted source (user
// input).
// The URI is validated by calling Windows.Foundation.Uri that will throw an exception for
// strings that are not valid URIs.
// Note that when enabling the text box users may provide URIs to machines on the intranet
// that require the "Private Networks (Client and Server)" capability.
var remoteAddress = remoteAddressField.value.trim();
try {
var uri = new Windows.Foundation.Uri(remoteAddress);
}
catch (error) {
WinJS.log("Invalid URI.", "sample", "error");
return;
}
var fileName = fileNameField.value.trim();
if (fileName == "") {
WinJS.log("A local file name is required.", "sample", "error");
return;
}
// Try to create some downloads.
var createDownloadPromises = [];
for (var i = 0; i < NumDownloads; i++) {
createDownloadPromises.push(
createDownloadAsync(downloader, remoteAddress + "?id=" + i, i + "." + fileName));
}
return WinJS.Promise.join(createDownloadPromises).then(function (downloads) {
// Once all downloads have been created, start them.
var downloadPromises = [];
for (var i = 0; i < downloads.length; i++) {
var downloadCollectionItem = downloadCollection[i];
downloadPromises.push(downloadCollectionItem.startAsync(downloads[i]));
}
WinJS.Promise.join(downloadPromises).done(done_callback);
});
}
function createDownloadAsync(downloader, remoteAddress, fileName) {
return Windows.Storage.KnownFolders.picturesLibrary.createFileAsync(
fileName,
Windows.Storage.CreationCollisionOption.generateUniqueName).then(function (destinationFile) {
var source = new Windows.Foundation.Uri(remoteAddress);
return downloader.createDownload(source, destinationFile);
}, function (e) {
WinJS.log(`Error while creating file: ${e.message}`, "sample", "error");
}
);
}
function isWebException(title, ex, download) {
var error = BackgroundTransfer.BackgroundTransferError.getStatus(ex.number);
var result = (error != Windows.Web.WebErrorStatus.unknown);
var message = result ? SdkSample.lookupEnumName(Windows.Web.WebErrorStatus, error) : ex.message;
if (download == null) {
WinJS.log(`${title}: ${message}`, "sample", "error");
} else {
WinJS.log(`${download.resultFile.name} - ${title}: ${message}`, "sample", "error");
}
return result;
}
})();

Просмотреть файл

@ -19,7 +19,7 @@
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.16299.0" MaxVersionTested="10.0.16299.0" />
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17069.0" MaxVersionTested="10.0.17069.0" />
</Dependencies>
<Resources>

Просмотреть файл

@ -0,0 +1,41 @@
<!--
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
-->
<Page x:Class="SDKTemplate.Scenario7_DownloadReordering" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="using:SDKTemplate" mc:Ignorable="d">
<ScrollViewer HorizontalScrollMode="Disabled" VerticalScrollMode="Enabled" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<StackPanel x:Name="LayoutRoot">
<TextBlock x:Name="InputTextBlock1" TextWrapping="Wrap" Grid.Row="0" Style="{StaticResource BasicTextStyle}">
Transfers which belong to the same transfer group can be reordered after they have been started.
</TextBlock>
<TextBlock Text="Remote address: " Style="{StaticResource BasicTextStyle}" Margin="0,8,10,0" />
<TextBox x:Name="remoteAddressField" InputScope="Url" Text="http://localhost/BackgroundTransferSample/download.aspx" />
<TextBlock Text="Local file name: " Style="{StaticResource BasicTextStyle}" Margin="0,8,17,0" />
<TextBox x:Name="fileNameField" Text="DownloadReordering.txt" />
<StackPanel Grid.Row="3" Orientation="Horizontal" Margin="0,10,0,0">
<Button x:Name="startDownloadButton" Content="Start Download" Margin="0,0,10,0" Click="StartDownload_Click" />
</StackPanel>
<TextBlock Text="Select a pending transfer to reorder the downloads." Style="{StaticResource BasicTextStyle}" Margin="0,8,17,0" />
<ListView ItemsSource="{x:Bind downloadCollection, Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:DownloadOperationItem">
<StackPanel Orientation="Horizontal">
<Button Content="Make Current" Click="MakeCurrent_Click" />
<ProgressBar Margin="10,0,0,0" Height="30" Width="200" Minimum="0" Maximum="100" Value="{x:Bind percentComplete, Mode=OneWay}" Foreground="Green" />
<TextBlock Margin="10,0,0,0" Text="{x:Bind stateText, Mode=OneWay}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</ScrollViewer>
</Page>

Просмотреть файл

@ -92,7 +92,7 @@ Namespace Global.BackgroundTransfer
' Validating the URI is required since it was received from an untrusted source (user input).
' The URI is validated by calling Uri.TryCreate() that will return 'false' for strings that are not valid URIs.
' Note that when enabling the text box users may provide URIs to machines on the intrAnet that require
' the "Home or Work Networking" capability.
' the "Private Networks (Client and Server)" capability.
Dim source As Uri = Nothing
If Not Uri.TryCreate(serverAddressField.Text.Trim(), UriKind.Absolute, source) Then
rootPage.NotifyUser("Invalid URI.", NotifyType.ErrorMessage)

Просмотреть файл

@ -93,7 +93,7 @@ Namespace Global.BackgroundTransfer
' Validating the URI is required since it was received from an untrusted source (user input).
' The URI is validated by calling Uri.TryCreate() that will return 'false' for strings that are not valid URIs.
' Note that when enabling the text box users may provide URIs to machines on the intrAnet that require
' the "Home or Work Networking" capability.
' the "Private Networks (Client and Server)" capability.
Dim uri As Uri = Nothing
If Not Uri.TryCreate(serverAddressField.Text.Trim(), UriKind.Absolute, uri) Then
rootPage.NotifyUser("Invalid URI.", NotifyType.ErrorMessage)
@ -129,7 +129,7 @@ Namespace Global.BackgroundTransfer
' box validating the URI is required since it was received from an untrusted source (user input).
' The URI is validated by calling Uri.TryCreate() that will return 'false' for strings that are not valid URIs.
' Note that when enabling the text box users may provide URIs to machines on the intrAnet that require
' the "Home or Work Networking" capability.
' the "Private Networks (Client and Server)" capability.
Dim uri As Uri = Nothing
If Not Uri.TryCreate(serverAddressField.Text.Trim(), UriKind.Absolute, uri) Then
rootPage.NotifyUser("Invalid URI.", NotifyType.ErrorMessage)

Просмотреть файл

@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
@ -39,5 +38,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -46,4 +46,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -13,6 +13,7 @@ using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Devices.Enumeration;
@ -63,6 +64,7 @@ namespace CameraGetPreviewFrame
private MediaCapture _mediaCapture;
private bool _isInitialized = false;
private bool _isPreviewing = false;
private static readonly SemaphoreSlim _mediaCaptureLifeLock = new SemaphoreSlim(1);
// Information about the camera device
private bool _mirroringPreview = false;
@ -93,7 +95,7 @@ namespace CameraGetPreviewFrame
await CleanupCameraAsync();
_displayInformation.OrientationChanged -= DisplayInformation_OrientationChanged;
deferral.Complete();
}
}
@ -213,6 +215,8 @@ namespace CameraGetPreviewFrame
{
Debug.WriteLine("InitializeCameraAsync");
await _mediaCaptureLifeLock.WaitAsync();
if (_mediaCapture == null)
{
// Attempt to get the back camera if one is available, but use any camera device if not
@ -221,6 +225,7 @@ namespace CameraGetPreviewFrame
if (cameraDevice == null)
{
Debug.WriteLine("No camera device found!");
_mediaCaptureLifeLock.Release();
return;
}
@ -242,6 +247,10 @@ namespace CameraGetPreviewFrame
{
Debug.WriteLine("The app was denied access to the camera");
}
finally
{
_mediaCaptureLifeLock.Release();
}
// If initialization succeeded, start the preview
if (_isInitialized)
@ -260,7 +269,7 @@ namespace CameraGetPreviewFrame
// Only mirror the preview if the camera is on the front panel
_mirroringPreview = (cameraDevice.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front);
}
await StartPreviewAsync();
var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
@ -268,6 +277,10 @@ namespace CameraGetPreviewFrame
_captureFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
}
}
else
{
_mediaCaptureLifeLock.Release();
}
}
/// <summary>
@ -436,24 +449,33 @@ namespace CameraGetPreviewFrame
/// <returns></returns>
private async Task CleanupCameraAsync()
{
if (_isInitialized)
await _mediaCaptureLifeLock.WaitAsync();
try
{
if (_isPreviewing)
if (_isInitialized)
{
// The call to stop the preview is included here for completeness, but can be
// safely removed if a call to MediaCapture.Dispose() is being made later,
// as the preview will be automatically stopped at that point
await StopPreviewAsync();
if (_isPreviewing)
{
// The call to stop the preview is included here for completeness, but can be
// safely removed if a call to MediaCapture.Dispose() is being made later,
// as the preview will be automatically stopped at that point
await StopPreviewAsync();
}
_isInitialized = false;
}
_isInitialized = false;
if (_mediaCapture != null)
{
_mediaCapture.Failed -= MediaCapture_Failed;
_mediaCapture.Dispose();
_mediaCapture = null;
}
}
if (_mediaCapture != null)
finally
{
_mediaCapture.Failed -= MediaCapture_Failed;
_mediaCapture.Dispose();
_mediaCapture = null;
_mediaCaptureLifeLock.Release();
}
}

Просмотреть файл

@ -13,7 +13,13 @@
#include "MainPage.xaml.h"
#include "SampleConfiguration.h"
using namespace Concurrency;
using namespace SDKTemplate;
using namespace Windows::Devices;
using namespace Windows::Devices::Enumeration;
using namespace Windows::Media::Capture;
using namespace Windows::Media::MediaProperties;
using namespace Windows::UI::Xaml::Controls;
Platform::Array<Scenario>^ MainPage::scenariosInner = ref new Platform::Array<Scenario>
{
@ -21,3 +27,23 @@ Platform::Array<Scenario>^ MainPage::scenariosInner = ref new Platform::Array<Sc
{ "Change preview and photo settings", "SDKTemplate.Scenario2_PhotoSettings" },
{ "Match aspect ratios", "SDKTemplate.Scenario3_AspectRatio" }
};
/// <summary>
/// Sets encoding properties on a camera stream. Ensures CaptureElement and preview stream are stopped before setting properties.
/// </summary>
task<void> MainPage::SetMediaStreamPropertiesAsync(MediaCapture^ mediaCapture, CaptureElement^ previewControl, MediaStreamType streamType, IMediaEncodingProperties^ encodingProperties)
{
// Stop preview and unlink the CaptureElement from the MediaCapture object
return create_task(mediaCapture->StopPreviewAsync())
.then([this, mediaCapture, previewControl, streamType, encodingProperties]()
{
previewControl->Source = nullptr;
// Apply desired stream properties
return create_task(mediaCapture->VideoDeviceController->SetMediaStreamPropertiesAsync(streamType, encodingProperties));
}).then([this, mediaCapture, previewControl]() {
// Recreate the CaptureElement pipeline and restart the preview
previewControl->Source = mediaCapture;
return create_task(mediaCapture->StartPreviewAsync());
});
}

Просмотреть файл

@ -35,6 +35,8 @@ namespace SDKTemplate
}
}
Concurrency::task<void> SetMediaStreamPropertiesAsync(Windows::Media::Capture::MediaCapture^ mediaCapture, Windows::UI::Xaml::Controls::CaptureElement^ previewControl, Windows::Media::Capture::MediaStreamType streamType, Windows::Media::MediaProperties::IMediaEncodingProperties ^ encodingProperties);
private:
static Platform::Array<Scenario>^ scenariosInner;
};

Просмотреть файл

@ -142,7 +142,7 @@ void Scenario1_PreviewSettings::ComboBoxSettings_Changed(Platform::Object^ sende
{
auto selectedItem = static_cast<ComboBoxItem^>(static_cast<ComboBox^>(sender)->SelectedItem);
auto encodingProperties = static_cast<IMediaEncodingProperties^>(selectedItem->Tag);
create_task(_mediaCapture->VideoDeviceController->SetMediaStreamPropertiesAsync(MediaStreamType::VideoPreview, encodingProperties));
create_task(_rootPage->SetMediaStreamPropertiesAsync(_mediaCapture.Get(), PreviewControl, MediaStreamType::VideoPreview, encodingProperties));
}
}

Просмотреть файл

@ -192,7 +192,7 @@ void Scenario2_PhotoSettings::PreviewSettings_Changed(Platform::Object^ sender,
{
auto selectedItem = static_cast<ComboBoxItem^>(static_cast<ComboBox^>(sender)->SelectedItem);
auto encodingProperties = static_cast<IMediaEncodingProperties^>(selectedItem->Tag);
create_task(_mediaCapture->VideoDeviceController->SetMediaStreamPropertiesAsync(MediaStreamType::VideoPreview, encodingProperties));
create_task(_rootPage->SetMediaStreamPropertiesAsync(_mediaCapture.Get(), PreviewControl, MediaStreamType::VideoPreview, encodingProperties));
}
}
@ -206,7 +206,7 @@ void Scenario2_PhotoSettings::PhotoSettings_Changed(Platform::Object^ sender, Wi
{
auto selectedItem = static_cast<ComboBoxItem^>(static_cast<ComboBox^>(sender)->SelectedItem);
auto encodingProperties = static_cast<IMediaEncodingProperties^>(selectedItem->Tag);
create_task(_mediaCapture->VideoDeviceController->SetMediaStreamPropertiesAsync(MediaStreamType::Photo, encodingProperties));
create_task(_rootPage->SetMediaStreamPropertiesAsync(_mediaCapture.Get(), PreviewControl, MediaStreamType::Photo, encodingProperties));
}
}

Просмотреть файл

@ -210,7 +210,7 @@ void Scenario3_AspectRatio::PreviewSettings_Changed(Platform::Object^ sender, Wi
{
auto selectedItem = static_cast<ComboBoxItem^>(static_cast<ComboBox^>(sender)->SelectedItem);
auto encodingProperties = static_cast<IMediaEncodingProperties^>(selectedItem->Tag);
create_task(_mediaCapture->VideoDeviceController->SetMediaStreamPropertiesAsync(MediaStreamType::VideoPreview, encodingProperties));
create_task(_rootPage->SetMediaStreamPropertiesAsync(_mediaCapture.Get(), PreviewControl, MediaStreamType::VideoPreview, encodingProperties));
// The preview just changed, update the video combo box
MatchPreviewAspectRatio();
@ -227,7 +227,7 @@ void Scenario3_AspectRatio::VideoSettings_Changed(Platform::Object^ sender, Wind
{
auto selectedItem = static_cast<ComboBoxItem^>(static_cast<ComboBox^>(sender)->SelectedItem);
auto encodingProperties = static_cast<IMediaEncodingProperties^>(selectedItem->Tag);
create_task(_mediaCapture->VideoDeviceController->SetMediaStreamPropertiesAsync(MediaStreamType::VideoRecord, encodingProperties));
create_task(_rootPage->SetMediaStreamPropertiesAsync(_mediaCapture.Get(), PreviewControl, MediaStreamType::VideoRecord, encodingProperties));
}
}

Просмотреть файл

@ -14,6 +14,7 @@ using System.Collections.Generic;
using Windows.UI.Xaml.Controls;
using Windows.Media.Capture;
using Windows.UI.Core;
using Windows.Media.MediaProperties;
namespace SDKTemplate
{
@ -50,6 +51,22 @@ namespace SDKTemplate
public bool IsRecording { get; set; }
public MediaCapture MediaCapture { get; private set; }
/// <summary>
/// Sets encoding properties on a camera stream. Ensures CaptureElement and preview stream are stopped before setting properties.
/// </summary>
public async Task SetMediaStreamPropertiesAsync(MediaStreamType streamType, IMediaEncodingProperties encodingProperties)
{
// Stop preview and unlink the CaptureElement from the MediaCapture object
await MediaCapture.StopPreviewAsync();
_previewControl.Source = null;
// Apply desired stream properties
await MediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, encodingProperties);
// Recreate the CaptureElement pipeline and restart the preview
_previewControl.Source = MediaCapture;
await MediaCapture.StartPreviewAsync();
}
/// <summary>
/// Initializes the MediaCapture, starts preview.

Просмотреть файл

@ -79,7 +79,7 @@ namespace SDKTemplate
{
var selectedItem = (sender as ComboBox).SelectedItem as ComboBoxItem;
var encodingProperties = (selectedItem.Tag as StreamResolution).EncodingProperties;
await _previewer.MediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, encodingProperties);
await _previewer.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, encodingProperties);
}
}

Просмотреть файл

@ -107,7 +107,7 @@ namespace SDKTemplate
{
var selectedItem = (sender as ComboBox).SelectedItem as ComboBoxItem;
var encodingProperties = (selectedItem.Tag as StreamResolution).EncodingProperties;
await _previewer.MediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, encodingProperties);
await _previewer.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, encodingProperties);
}
}

Просмотреть файл

@ -111,7 +111,7 @@ namespace SDKTemplate
{
var selectedItem = (sender as ComboBox).SelectedItem as ComboBoxItem;
var encodingProperties = (selectedItem.Tag as StreamResolution).EncodingProperties;
await _previewer.MediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, encodingProperties);
await _previewer.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, encodingProperties);
// The preview just changed, update the video combo box
MatchPreviewAspectRatio();

Просмотреть файл

@ -84,7 +84,7 @@
if (cameraSettings.value == "")
return;
mediaCapture.videoDeviceController.setMediaStreamPropertiesAsync(Capture.MediaStreamType.videoPreview, allProperties[cameraSettings.value]);
setMediaStreamPropertiesAsync(mediaCapture, Capture.MediaStreamType.videoPreview, allProperties[cameraSettings.value]);
}
}

Просмотреть файл

@ -101,7 +101,7 @@
if (previewSettings.value == "")
return;
mediaCapture.videoDeviceController.setMediaStreamPropertiesAsync(Capture.MediaStreamType.videoPreview, previewProperties[previewSettings.value]);
setMediaStreamPropertiesAsync(mediaCapture, Capture.MediaStreamType.videoPreview, previewProperties[previewSettings.value]);
}
}
@ -114,7 +114,7 @@
if (photoSettings.value == "")
return;
mediaCapture.videoDeviceController.setMediaStreamPropertiesAsync(Capture.MediaStreamType.videoPreview, photoProperties[photoSettings.value]);
setMediaStreamPropertiesAsync(mediaCapture, Capture.MediaStreamType.videoPreview, photoProperties[photoSettings.value]);
}
}

Просмотреть файл

@ -113,7 +113,7 @@
if (previewSettings.value == "")
return;
console.log(previewSettings.value)
mediaCapture.videoDeviceController.setMediaStreamPropertiesAsync(Capture.MediaStreamType.videoPreview, previewProperties[previewSettings.value]);
setMediaStreamPropertiesAsync(mediaCapture, Capture.MediaStreamType.videoPreview, previewProperties[previewSettings.value]);
// The preview just changed, update the video combo box
MatchPreviewAspectRatio();
@ -128,7 +128,7 @@
// The first element is just text
if (videoSettings.value == "")
return;
mediaCapture.videoDeviceController.setMediaStreamPropertiesAsync(Capture.MediaStreamType.videoRecord, videoProperties[videoSettings.value]);
setMediaStreamPropertiesAsync(mediaCapture, Capture.MediaStreamType.videoRecord, videoProperties[videoSettings.value]);
}
}

Просмотреть файл

@ -61,3 +61,23 @@ streamResolutionHelper.prototype.frameRate = function () {
streamResolutionHelper.prototype.aspectRatio = function () {
return (this.width() / this.height()).toFixed(2);
}
/// <summary>
/// Sets encoding properties on a camera stream. Ensures VideoElement and preview stream are stopped before setting properties.
/// </summary>
function setMediaStreamPropertiesAsync(mediaCapture, streamType, encodingProperties) {
// Stop preview and unlink the VideoElement from the MediaCapture object
var previewVidTag = document.getElementById("cameraPreview");
previewVidTag.pause;
previewVidTag.src = null;
// Apply desired stream properties
return mediaCapture.videoDeviceController.setMediaStreamPropertiesAsync(streamType, encodingProperties)
.then(function () {
// Recreate pipeline and restart the preview
var previewVidTag = document.getElementById("cameraPreview");
var previewUrl = URL.createObjectURL(mediaCapture);
previewVidTag.src = previewUrl;
previewVidTag.play();
});
}

Просмотреть файл

@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
@ -39,5 +38,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -12,7 +12,7 @@
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.15063.0</TargetPlatformMinVersion>
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>15</MinimumVisualStudioVersion>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
<FileAlignment>512</FileAlignment>

Просмотреть файл

@ -21,7 +21,7 @@
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.15063.0" MaxVersionTested="10.0.15063.0" />
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.15063.0" MaxVersionTested="10.0.16299.0" />
</Dependencies>
<Resources>

Просмотреть файл

@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
@ -39,5 +38,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
@ -39,5 +38,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
@ -39,5 +38,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
@ -39,5 +38,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
@ -53,5 +52,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -52,5 +52,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -15,8 +15,12 @@ using namespace Windows::Graphics::Holographic;
static const std::wstring s_VertexShaderFiles[DX::VertexShader_Max] =
{
L"ms-appx:///VertexShader.cso",
L"ms-appx:///VprtVertexShader.cso",
L"ms-appx:///VertexShaderTexture.cso",
};
static const std::wstring s_VprtVertexShaderFiles[DX::VertexShader_Max] =
{
L"ms-appx:///VprtVertexShader.cso",
L"ms-appx:///VprtVertexShaderTexture.cso"
};
@ -393,7 +397,7 @@ Concurrency::task<void> DX::DeviceResources::LoadShaders()
// Load vertex shaders and input layouts
for (int i = 0; i < VertexShader_Max; i++)
{
Concurrency::task<std::vector<byte>> loadVSTask = DX::ReadDataAsync(s_VertexShaderFiles[i]);
Concurrency::task<std::vector<byte>> loadVSTask = DX::ReadDataAsync(m_supportsVprt ? s_VprtVertexShaderFiles[i] : s_VertexShaderFiles[i]);
Concurrency::task<void> createVSTask = loadVSTask.then([this, i](const std::vector<byte>& fileData)
{
@ -407,7 +411,6 @@ Concurrency::task<void> DX::DeviceResources::LoadShaders()
switch (i)
{
case VertexShader_Simple:
case VertexShader_VPRT:
{
const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
{
@ -425,7 +428,6 @@ Concurrency::task<void> DX::DeviceResources::LoadShaders()
}
break;
case VertexShader_Texture:
case VertexShader_TextureVPRT:
{
const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
{

Просмотреть файл

@ -9,9 +9,7 @@ namespace DX
typedef enum
{
VertexShader_Simple = 0,
VertexShader_VPRT,
VertexShader_Texture,
VertexShader_TextureVPRT,
VertexShader_Max
} VertexShaderIndex;

Просмотреть файл

@ -220,8 +220,8 @@ void Button::DoCreateDeviceDependentResources()
// target array index, thus avoiding any overhead that would be
// incurred by setting the geometry shader stage.
m_vertexShader = m_deviceResources->GetVertexShader(m_usingVprtShaders ? DX::VertexShader_TextureVPRT : DX::VertexShader_Texture);
m_inputLayout = m_deviceResources->GetInputLayout(m_usingVprtShaders ? DX::VertexShader_TextureVPRT : DX::VertexShader_Texture);
m_vertexShader = m_deviceResources->GetVertexShader(DX::VertexShader_Texture);
m_inputLayout = m_deviceResources->GetInputLayout(DX::VertexShader_Texture);
m_pixelShader = m_deviceResources->GetPixelShader(DX::PixelShader_Texture);
D3D11_TEXTURE2D_DESC texDesc;

Просмотреть файл

@ -154,8 +154,8 @@ void Cursor::CreateDeviceDependentResources()
// target array index, thus avoiding any overhead that would be
// incurred by setting the geometry shader stage.
m_vertexShader = m_deviceResources->GetVertexShader(m_usingVprtShaders ? DX::VertexShader_TextureVPRT : DX::VertexShader_Texture);
m_inputLayout = m_deviceResources->GetInputLayout(m_usingVprtShaders ? DX::VertexShader_TextureVPRT : DX::VertexShader_Texture);
m_vertexShader = m_deviceResources->GetVertexShader(DX::VertexShader_Texture);
m_inputLayout = m_deviceResources->GetInputLayout(DX::VertexShader_Texture);
m_pixelShader = m_deviceResources->GetPixelShader(DX::PixelShader_Cursor);
D3D11_TEXTURE2D_DESC texDesc;

Просмотреть файл

@ -145,8 +145,8 @@ void Panel::DoCreateDeviceDependentResources()
// target array index, thus avoiding any overhead that would be
// incurred by setting the geometry shader stage.
m_vertexShader = m_deviceResources->GetVertexShader(m_usingVprtShaders ? DX::VertexShader_VPRT : DX::VertexShader_Simple);
m_inputLayout = m_deviceResources->GetInputLayout(m_usingVprtShaders ? DX::VertexShader_VPRT : DX::VertexShader_Simple);
m_vertexShader = m_deviceResources->GetVertexShader(DX::VertexShader_Simple);
m_inputLayout = m_deviceResources->GetInputLayout(DX::VertexShader_Simple);
m_pixelShader = m_deviceResources->GetPixelShader(DX::PixelShader_Simple);
if (!m_usingVprtShaders)

Просмотреть файл

@ -166,8 +166,8 @@ void SpinningCubeRenderer::CreateDeviceDependentResources()
// target array index, thus avoiding any overhead that would be
// incurred by setting the geometry shader stage.
m_vertexShader = m_deviceResources->GetVertexShader(m_usingVprtShaders ? DX::VertexShader_VPRT : DX::VertexShader_Simple);
m_inputLayout = m_deviceResources->GetInputLayout(m_usingVprtShaders ? DX::VertexShader_VPRT : DX::VertexShader_Simple);
m_vertexShader = m_deviceResources->GetVertexShader(DX::VertexShader_Simple);
m_inputLayout = m_deviceResources->GetInputLayout(DX::VertexShader_Simple);
m_pixelShader = m_deviceResources->GetPixelShader(DX::PixelShader_Simple);
if (!m_usingVprtShaders)

Просмотреть файл

@ -517,8 +517,8 @@ void HolographicMRCSampleMain::OnButtonInitTapped()
{
Concurrency::create_task(m_mediaCapture->InitializeAsync()).then([this]()
{
m_photoButton->SetEnabled(true);
m_videoButton->SetEnabled(true);
m_photoButton->SetEnabled(m_mediaCapture->CanTakePhoto());
m_videoButton->SetEnabled(m_mediaCapture->CanToggleVideo());
m_hologramButton->SetEnabled(true);
m_sysAudioButton->SetEnabled(true);
});
@ -544,7 +544,7 @@ void HolographicMRCSampleMain::OnButtonVideoTapped()
m_initButton->SetEnabled(false);
m_photoButton->SetEnabled(m_mediaCapture->CanTakePhoto());
m_videoButton->SetEnabled(true);
m_videoButton->SetEnabled(m_mediaCapture->CanToggleVideo());
m_hologramButton->SetEnabled(true);
m_sysAudioButton->SetEnabled(true);
});
@ -565,7 +565,7 @@ void HolographicMRCSampleMain::OnButtonVideoTapped()
m_initButton->SetEnabled(false);
m_photoButton->SetEnabled(m_mediaCapture->CanTakePhoto());
m_videoButton->SetEnabled(true);
m_videoButton->SetEnabled(m_mediaCapture->CanToggleVideo());
m_hologramButton->SetEnabled(false);
m_sysAudioButton->SetEnabled(false);
});
@ -587,7 +587,7 @@ void HolographicMRCSampleMain::OnButtonPhotoTapped()
{
m_initButton->SetEnabled(false);
m_photoButton->SetEnabled(m_mediaCapture->CanTakePhoto());
m_videoButton->SetEnabled(true);
m_videoButton->SetEnabled(m_mediaCapture->CanToggleVideo());
m_hologramButton->SetEnabled(true);
m_sysAudioButton->SetEnabled(true);
});

Просмотреть файл

@ -49,7 +49,16 @@ Concurrency::task<void> MediaCaptureManager::InitializeAsync(IMFDXGIDeviceManage
return Concurrency::create_task(m_mediaCapture->InitializeAsync(initSetting)).then([this]()
{
auto lock = m_lock.LockExclusive();
m_currentState = Initialized;
if (m_mediaCapture->MediaCaptureSettings->AudioDeviceId && m_mediaCapture->MediaCaptureSettings->VideoDeviceId)
{
// MediaCapture is initialized with valid audio and video device.
m_currentState = Initialized;
}
else
{
OutputDebugString(L"MediaCapture is initialized without valid sources.\n");
}
});
}
@ -295,14 +304,21 @@ bool MediaCaptureManager::CanTakePhoto()
if (m_currentState == Initialized)
{
OutputDebugString(L"Can Take Photo\n");
ret = true;
}
else
{
OutputDebugString(L"Can NOT Take Photo\n");
ret = false;
}
return ret;
}
bool MediaCaptureManager::CanToggleVideo()
{
auto lock = m_lock.LockShared();
bool ret = false;
if (m_currentState == Initialized || m_currentState == Recording)
{
ret = true;
}
return ret;
}

Просмотреть файл

@ -35,6 +35,7 @@ namespace HolographicMRCSample
bool IsHologramEnabled() { auto lock = m_lock.LockShared(); return m_hologramEnabled; }
bool IsSystemAudioEnabled() { auto lock = m_lock.LockShared(); return m_sysAudioEnabled; }
bool CanTakePhoto();
bool CanToggleVideo();
private:
Microsoft::WRL::Wrappers::SRWLock m_lock;

Просмотреть файл

@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
@ -39,5 +38,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -23,6 +23,7 @@ Specifically, this sample covers using the [Windows.UI.Input.Inking](http://msdn
- Delete ink strokes
- Recognize handwriting from ink strokes
- Search for a string within recognition results
- Obtain the InkPresenter for a canvas
**Note**  Read the following instructions before using the app.

Просмотреть файл

@ -45,8 +45,8 @@
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" />
<PropertyGroup>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
<TargetPlatformVersion>10.0.17069.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17069.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>$(VersionNumberMajor).$(VersionNumberMinor)</MinimumVisualStudioVersion>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
@ -55,8 +55,10 @@
<SubType>Designer</SubType>
</AppxManifest>
<Content Include="css\scenario1.css" />
<Content Include="css\scenario2.css" />
<Content Include="default.html" />
<Content Include="html\scenario1.html" />
<Content Include="html\scenario2.html" />
<Content Include="images\Erase.cur" />
<Content Include="..\..\..\SharedContent\media\microsoft-sdk.png">
<Link>images\microsoft-sdk.png</Link>
@ -85,6 +87,7 @@
</Content>
<Content Include="js\sample-configuration.js" />
<Content Include="js\scenario1.js" />
<Content Include="js\scenario2.js" />
<Content Include="..\..\..\SharedContent\js\Microsoft.WinJS\css\ui-dark.css">
<Link>Microsoft.WinJS.4.0\css\ui-dark.css</Link>
</Content>

Просмотреть файл

@ -0,0 +1,77 @@
/*
Copyright (c) Microsoft Corporation. All rights reserved
*/
{
-ms-content-zooming: none;
}
body
{
touch-action: none;
}
#scenarioHeader
{
flex-shrink: 0;
}
#scenarioView
{
display: flex;
flex-direction: column;
height: 100%;
}
#scenarioContent
{
display: flex;
flex-direction: column;
height: 100%;
}
#canvasGroup {
display: block;
position: relative;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
width: 100%;
height: 100%;
overflow: scroll;
z-index: 0;
pen-action: none;
}
canvas.surface {
display: block;
position: absolute;
width: 2560px;
height: 2560px;
}
#ToolBar
{
flex-shrink: 0;
}
#Black .win-label
{
color: Black;
}
#Blue .win-label
{
color: Blue;
}
#Red .win-label
{
color: Red;
}
#Green .win-label
{
color: Green;
}

Просмотреть файл

@ -0,0 +1,49 @@
<!--
Copyright (c) Microsoft Corporation. All rights reserved
-->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" href="/css/scenario2.css">
<script src="/js/scenario2.js"></script>
</head>
<body class="win-type-body">
<div id="scenarioView">
<div id="scenarioHeader">
<h2 id="sampleHeader" class="win-type-subheader">Description:</h2>
<div id="scenarioDescription">
Demonstrates use of Ink Presenter APIs.
</div>
</div>
<div id="scenarioContent">
<div id="canvasGroup">
<canvas id="InkCanvas" class="surface"></canvas>
</div>
<!-- This toolbar is displayed across the bottom of the screen.
The color buttons have IDs which are the names of colors; the ID of each one is fed directly into the strokeStyle of the corresponding canvas.-->
<div id="ToolBar" data-win-control="WinJS.UI.ToolBar">
<button data-win-control="WinJS.UI.Command" data-win-options="{id:&apos;Undo&apos;, label:&apos;Undo&apos;, icon:&apos;undo&apos;, onclick:Ink.undo, section:&apos;primary&apos;, tooltip:&apos;Undo&apos;, priority:2}" class="win-button"></button>
<hr data-win-control="WinJS.UI.Command" data-win-options="{type:&apos;separator&apos;}">
<button data-win-control="WinJS.UI.Command" data-win-options="{id:&apos;InkColors&apos;, label:&apos;Color&apos;, icon:&apos;fontcolor&apos;, section:&apos;primary&apos;, type:&apos;flyout&apos;,flyout:&apos;InkColorFlyout&apos;, tooltip:&apos;Choose ink color&apos;, priority:2}" class="win-button"></button>
<hr data-win-control="WinJS.UI.Command" data-win-options="{type:&apos;separator&apos;}">
<button data-win-control="WinJS.UI.Command" data-win-options="{id:&apos;ModeErase&apos;, label:&apos;Erase&apos;, icon:&apos;dockleft&apos;, onclick:Ink.eraseMode, section:&apos;primary&apos;, tooltip:&apos;Switch pen tip to eraser mode&apos;, priority:2}" class="win-button"></button>
<button data-win-control="WinJS.UI.Command" data-win-options="{id:&apos;Pencil&apos;, label:&apos;Pencil&apos;, icon:&apos;edit&apos;, onclick:Ink.pencilMode, section:&apos;primary&apos;, tooltip:&apos;Switch pen tip to pencil mode&apos;, priority:2}" class="win-button"></button>
<button data-win-control="WinJS.UI.Command" data-win-options="{id:&apos;Highlighter&apos;, label:&apos;Highlighter&apos;, icon:&apos;highlight&apos;, onclick:Ink.highlighterMode, section:&apos;primary&apos;, tooltip:&apos;Switch to highlighter mode&apos;, priority:2}" class="win-button"></button>
<button data-win-control="WinJS.UI.Command" data-win-options="{id:&apos;Load&apos;,label:&apos;Load&apos;,onclick:Ink.load,section:&apos;secondary&apos;}" class="win-button"></button>
<button data-win-control="WinJS.UI.Command" data-win-options="{id:&apos;Save&apos;,label:&apos;Save&apos;,onclick:Ink.save,section:&apos;secondary&apos;}" class="win-button"></button>
<button data-win-control="WinJS.UI.Command" data-win-options="{id:&apos;Clear&apos;,label:&apos;Clear&apos;,onclick:Ink.clear,section:&apos;secondary&apos;}" class="win-button"></button>
</div>
</div>
</div>
</body>
</html>

Просмотреть файл

@ -6,7 +6,8 @@
var sampleTitle = "Ink sample";
var scenarios = [
{ url: "/html/scenario1.html", title: "Scenario 1" }
{ url: "/html/scenario1.html", title: "Scenario 1" },
{ url: "/html/scenario2.html", title: "Scenario 2" }
];
WinJS.Namespace.define("SdkSample", {

Просмотреть файл

@ -0,0 +1,205 @@
//// Copyright (c) Microsoft Corporation. All rights reserved
// Sample app demonstrating the use of InkPresenter APIs.
(function () {
"use strict";
// abbreviations
var Inking = Windows.UI.Input.Inking;
var InkInputProcessingMode = Inking.InkInputProcessingMode;
function displayStatus(message) {
WinJS.log && WinJS.log(message, "sample", "status");
}
function displayError(message) {
WinJS.log && WinJS.log(message, "sample", "error");
}
var STROKES_FILENAME = "strokes.txt";
var inkCanvas;
var inkContext;
var inkPresenter;
var inkColor;
// Undo the last stroke by removing it from the stroke container.
function undo() {
var strokeContainer = inkPresenter.strokeContainer;
var strokes = strokeContainer.getStrokes();
// If there are no strokes, there's nothing to undo.
if (strokes.length == 0) {
return;
}
// Select the last stroke and delete it.
strokes[strokes.length - 1].selected = true;
strokeContainer.deleteSelected();
}
// Switch pen tip to eraser mode.
function eraseMode() {
inkPresenter.inputProcessingConfiguration.mode = InkInputProcessingMode.erasing;
}
// Switch pen tip to pencil mode.
function pencilMode() {
var drawingAttributes = new Inking.InkDrawingAttributes.createForPencil();
drawingAttributes.ignorePressure = false;
drawingAttributes.fitToCurve = true;
drawingAttributes.color = inkColor;
drawingAttributes.size = { width: 3, height: 3 };
inkPresenter.updateDefaultDrawingAttributes(drawingAttributes);
inkPresenter.inputProcessingConfiguration.mode = InkInputProcessingMode.inking
}
// Switch pen tip to highlighter mode.
function highlighterMode() {
var drawingAttributes = new Inking.InkDrawingAttributes();
drawingAttributes.ignorePressure = true;
drawingAttributes.fitToCurve = true;
drawingAttributes.drawAsHighlighter = true;
drawingAttributes.penTip = Inking.PenTipShape.rectangle;
drawingAttributes.size = { width: 10, height: 10 };
drawingAttributes.color = inkColor;
inkPresenter.updateDefaultDrawingAttributes(drawingAttributes);
inkPresenter.inputProcessingConfiguration.mode = InkInputProcessingMode.inking;
}
// Load the strokes from the file into the stroke container.
function load() {
var strokeContainer = inkPresenter.strokeContainer;
var loadStream;
var localAppDataFolder = Windows.Storage.ApplicationData.current.localFolder;
localAppDataFolder.getFileAsync(STROKES_FILENAME).then(function (file) {
// Open the file
return file.openAsync(Windows.Storage.FileAccessMode.read);
}).then(function (stream) {
// Load the strokes into the stroke container.
loadStream = stream;
return strokeContainer.loadAsync(stream)
}).done(function () {
// Input stream is IClosable interface and requires explicit close.
loadStream.close();
},
function () {
displayError("Load Failed. First save a file before loading one.");
});
}
// Save the strokes from the stroke container to a file.
function save() {
var strokeContainer = inkPresenter.strokeContainer;
var saveStream;
// Create or replace existing file.
var localAppDataFolder = Windows.Storage.ApplicationData.current.localFolder;
localAppDataFolder.createFileAsync(STROKES_FILENAME, Windows.Storage.CreationCollisionOption.replaceExisting).then(function (file) {
// Open the file
return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
}).then(function (stream) {
// Save the strokes to the file.
saveStream = stream;
return strokeContainer.saveAsync(stream);
}).then(function () {
return saveStream.flushAsync();
}).done(function () {
// Output stream is IClosable interface and requires explicit close.
saveStream.close();
});
}
// Clear the stroke container and display text.
function clear() {
inkPresenter.strokeContainer.clear();
displayStatus("");
displayError("");
}
// A button handler which fetches the ID from the button, which should be a color name.
// Set the ink presenter drawing attributes' color to that color.
function setInkColor(evt) {
switch (evt.currentTarget.id) {
case "Black":
inkColor = Windows.UI.Colors.black;
break;
case "Blue":
inkColor = Windows.UI.Colors.blue;
break;
case "Red":
inkColor = Windows.UI.Colors.red;
break;
case "Green":
inkColor = Windows.UI.Colors.green;
break;
}
var drawingAttributes = inkPresenter.copyDefaultDrawingAttributes();
drawingAttributes.color = inkColor;
inkPresenter.updateDefaultDrawingAttributes(drawingAttributes);
}
function inkInitialize() {
// Utility to fetch elements by ID.
function id(elementId) {
return document.getElementById(elementId);
}
WinJS.UI.processAll().then(
function () {
id("Black").addEventListener("click", setInkColor);
id("Blue").addEventListener("click", setInkColor);
id("Red").addEventListener("click", setInkColor);
id("Green").addEventListener("click", setInkColor);
inkCanvas = id("InkCanvas");
inkCanvas.setAttribute("width", inkCanvas.offsetWidth);
inkCanvas.setAttribute("height", inkCanvas.offsetHeight);
// Get the ms-ink context
inkContext = inkCanvas.getContext("ms-ink");
inkPresenter = inkContext.msInkPresenter;
inkPresenter.inputDeviceTypes =
Windows.UI.Core.CoreInputDeviceTypes.mouse |
Windows.UI.Core.CoreInputDeviceTypes.pen;
// Set the default drawing attributes.
inkColor = Windows.UI.Colors.black;
pencilMode();
}
).done(null, function (e) {
displayError("inkInitialize " + e.toString());
});
}
// Tag the event handlers of the ToolBar so that they can be used in a declarative context.
// For security reasons WinJS.UI.processAll and WinJS.Binding.processAll (and related) functions allow only
// functions that are marked as being usable declaratively to be invoked through declarative processing.
WinJS.UI.eventHandler(undo);
WinJS.UI.eventHandler(eraseMode);
WinJS.UI.eventHandler(pencilMode);
WinJS.UI.eventHandler(highlighterMode);
WinJS.UI.eventHandler(load);
WinJS.UI.eventHandler(save);
WinJS.UI.eventHandler(clear);
WinJS.Namespace.define("Ink", {
undo: undo,
eraseMode: eraseMode,
pencilMode: pencilMode,
highlighterMode: highlighterMode,
load: load,
save: save,
clear: clear,
});
var page = WinJS.UI.Pages.define("/html/scenario2.html", {
ready: function (element, options) {
inkInitialize();
}
});
})();

Просмотреть файл

@ -19,7 +19,7 @@
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.10240.0" MaxVersionTested="10.0.16299.0" />
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17069.0" MaxVersionTested="10.0.17069.0" />
</Dependencies>
<Resources>

Просмотреть файл

@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
@ -39,5 +38,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -29,7 +29,7 @@ Scenario2::Scenario2()
mapIconStreamReference = RandomAccessStreamReference::CreateFromUri(ref new Uri("ms-appx:///Assets/MapPin.png"));
mapBillboardStreamReference = RandomAccessStreamReference::CreateFromUri(ref new Uri("ms-appx:///Assets/billboard.jpg"));
mapModelStreamReference = RandomAccessStreamReference::CreateFromUri(ref new Uri("ms-appx:///Assets/ConkerAfro.3mf"));
mapModelStreamReference = RandomAccessStreamReference::CreateFromUri(ref new Uri("ms-appx:///Assets/box.3mf"));
}
void Scenario2::MyMap_Loaded(Object^ sender, RoutedEventArgs^ e)

Просмотреть файл

@ -281,7 +281,7 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\shared\box.3mf">
<Link>Assets\ConkerAfro.3mf</Link>
<Link>Assets\box.3mf</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\shared\MyCustomStates.json">

Просмотреть файл

@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
@ -39,5 +38,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -32,12 +32,18 @@
<StackPanel x:Name="RenderingPanel" Visibility="Collapsed">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock VerticalAlignment="center">View page</TextBlock>
<TextBox x:Name="PageNumberBox" InputScope="Number" Width="30" Text="1" TextAlignment="Right" Margin="5,0,5,0"/>
<TextBlock Name="ViewPageLabel" VerticalAlignment="center">View page</TextBlock>
<!-- Always give a TextBox a name that's accessible to a screen reader. In this case,
reference the labeling TextBlock to have the accessible name set on the TextBox. -->
<TextBox x:Name="PageNumberBox" InputScope="Number" Width="30" Text="1" TextAlignment="Right" Margin="5,0,5,0"
AutomationProperties.LabeledBy="{Binding ElementName=ViewPageLabel}"/>
<TextBlock VerticalAlignment="Center">of <Run x:Name="PageCountText"/>.</TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<ComboBox x:Name="Options" SelectedIndex="0">
<!-- Always give a ComboBox a name that's accessible to a screen reader. Given that there's no labeling
TextBlock to reference, explicitly set the accessible name on the ComboBox. A shipping app would
localize this name. -->
<ComboBox x:Name="Options" AutomationProperties.Name="View page size" SelectedIndex="0">
<ComboBoxItem>Actual size</ComboBoxItem>
<ComboBoxItem>Half size on beige background</ComboBoxItem>
<ComboBoxItem>Crop to center of page</ComboBoxItem>
@ -45,7 +51,9 @@
<Button Click="{x:Bind ViewPage}" Content="View" Margin="10,0,0,0"/>
</StackPanel>
<Image x:Name="Output" Stretch="None" Margin="0,10,0,0"/>
<!-- Always give an Image a name that's accessible to screen reader, (unless the Image is purely decorative.)
A shipping app would localize this name.-->
<Image x:Name="Output" AutomationProperties.Name="PDF document content" Stretch="None" Margin="0,10,0,0"/>
</StackPanel>
<ProgressRing x:Name="ProgressControl" Height="50" Width="50" IsActive="True" Visibility="Collapsed" Margin="0,10,0,0"/>
</StackPanel>

Просмотреть файл

@ -55,11 +55,10 @@
<RichTextBlockOverflow x:Name="ContinuationPageLinkedContainer" Grid.Row="3" Grid.ColumnSpan="2"/>
<Image Source="ms-appx:///Assets/print_1.png" x:Name="ScenarioImage" HorizontalAlignment="Center" Grid.Row="2" Grid.Column="1" Margin="10"/>
<StackPanel x:Name="Footer" Grid.Row="4" Grid.Column="0" VerticalAlignment="Top" Visibility="Collapsed">
<Image Source="ms-appx:///Assets/splash-sdk.png" HorizontalAlignment="Left" Stretch="None"/>
<RichTextBlock Foreground="Black" FontSize="16" TextAlignment="Left" FontFamily="Segoe UI">
<Paragraph>Copyright © Microsoft Corporation. All rights reserved.</Paragraph>
</RichTextBlock>
<StackPanel x:Name="Footer" Grid.Row="4" Grid.ColumnSpan="2">
<TextBlock Foreground="Black" FontSize="16" TextAlignment="Left" FontFamily="Segoe UI">
Copyright © Microsoft Corporation. All rights reserved.
</TextBlock>
</StackPanel>
</Grid>
</Page>

Просмотреть файл

@ -209,7 +209,8 @@ RichTextBlockOverflow^ PrintHelper::AddOnePrintPreviewPage(RichTextBlockOverflow
{
// If this is the first page add the specific scenario content
page = FirstPage;
//Hide footer since we don't know yet if it will be displayed (this might not be the last page) - wait for layout
// Hide footer since we don't know yet if it will be displayed (this might not be the last page) - wait for layout
StackPanel^ footer = safe_cast<StackPanel^>(page->FindName("Footer"));
footer->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
}
@ -248,6 +249,7 @@ RichTextBlockOverflow^ PrintHelper::AddOnePrintPreviewPage(RichTextBlockOverflow
{
StackPanel^ footer = safe_cast<StackPanel^>(page->FindName("Footer"));
footer->Visibility = Windows::UI::Xaml::Visibility::Visible;
PrintCanvas->UpdateLayout();
}
// Add the page to the page preview collection

Просмотреть файл

@ -103,7 +103,8 @@ RichTextBlockOverflow^ PreviewOptionsPrintHelper::AddOnePrintPage(RichTextBlockO
{
// If this is the first page add the specific scenario content
page = FirstPage;
//Hide footer since we don't know yet if it will be displayed (this might not be the last page) - wait for layout
// Hide footer since we don't know yet if it will be displayed (this might not be the last page) - wait for layout
StackPanel^ footer = safe_cast<StackPanel^>(page->FindName("Footer"));
footer->Visibility = Visibility::Collapsed;
}
@ -142,6 +143,7 @@ RichTextBlockOverflow^ PreviewOptionsPrintHelper::AddOnePrintPage(RichTextBlockO
{
StackPanel^ footer = safe_cast<StackPanel^>(page->FindName("Footer"));
footer->Visibility = Visibility::Visible;
PrintCanvas->UpdateLayout();
}
// Add the page to the page print collection

Просмотреть файл

@ -65,11 +65,10 @@
<RichTextBlockOverflow x:Name="ContinuationPageLinkedContainer" Grid.Row="3" Grid.ColumnSpan="2"/>
<Image Source="ms-appx:///Assets/print_1.png" x:Name="ScenarioImage" HorizontalAlignment="Center" Grid.Row="2" Grid.Column="1" Margin="10"/>
<StackPanel x:Name="Footer" Grid.Row="4" Grid.Column="0" VerticalAlignment="Top" Visibility="Collapsed">
<Image Source="ms-appx:///Assets/splash-sdk.png" HorizontalAlignment="Left" Stretch="None"/>
<RichTextBlock Foreground="Black" FontSize="16" TextAlignment="Left" FontFamily="Segoe UI">
<Paragraph>Copyright © Microsoft Corporation. All rights reserved.</Paragraph>
</RichTextBlock>
<StackPanel x:Name="Footer" Grid.Row="4" Grid.ColumnSpan="2">
<TextBlock Foreground="Black" FontSize="16" TextAlignment="Left" FontFamily="Segoe UI">
Copyright © Microsoft Corporation. All rights reserved.
</TextBlock>
</StackPanel>
</Grid>
</Page>

Просмотреть файл

@ -273,7 +273,8 @@ namespace PrintSample
{
// If this is the first page add the specific scenario content
page = firstPage;
//Hide footer since we don't know yet if it will be displayed (this might not be the last page) - wait for layout
// Hide footer since we don't know yet if it will be displayed (this might not be the last page) - wait for layout
StackPanel footer = (StackPanel)page.FindName("Footer");
footer.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
@ -312,6 +313,7 @@ namespace PrintSample
{
StackPanel footer = (StackPanel)page.FindName("Footer");
footer.Visibility = Windows.UI.Xaml.Visibility.Visible;
PrintCanvas.UpdateLayout();
}
// Add the page to the page preview collection

Просмотреть файл

@ -144,7 +144,8 @@ namespace PrintSample
{
// If this is the first page add the specific scenario content
page = firstPage;
//Hide footer since we don't know yet if it will be displayed (this might not be the last page) - wait for layout
// Hide footer since we don't know yet if it will be displayed (this might not be the last page) - wait for layout
StackPanel footer = (StackPanel)page.FindName("Footer");
footer.Visibility = Visibility.Collapsed;
}
@ -183,6 +184,7 @@ namespace PrintSample
{
StackPanel footer = (StackPanel)page.FindName("Footer");
footer.Visibility = Visibility.Visible;
PrintCanvas.UpdateLayout();
}
// Add the page to the print page collection

Просмотреть файл

@ -49,65 +49,81 @@
<ScrollViewer Grid.Row="1">
<StackPanel Orientation="Vertical">
<GridView IsItemClickEnabled="False" SelectionMode="None">
<!-- Provide an AutomationProperties.Name for a GridView to a screen reader. A shipping app would localize this. -->
<GridView AutomationProperties.Name="Radial Controller Events Hookup" IsItemClickEnabled="False" SelectionMode="None">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<StackPanel Style="{StaticResource ButtonGroup}">
<Image Height="64" Width="64" HorizontalAlignment="Left" Source="Assets\Item0.png"/>
<!-- All shipping GridView items must have helpful, concise, localized and unique accessible names, so that
a screen reader can make your customers aware of their purpose. Given that this sample defines each item
here, (are the items are not databound,) set the accessible names on each item explicitly. This sample
contains placeholder text which would be replaced with appropriate localized text by a shipping app. -->
<!-- All shipping Images, Sliders, and ToggleSwitches must have helpful, concise, localized and unique
accessible names, so that a screen reader can make your customers aware of their purpose. This sample
contains placeholder text which would be replaced with appropriate localized text by a shipping app. -->
<StackPanel AutomationProperties.Name="Item 0 details" Style="{StaticResource ButtonGroup}">
<Image AutomationProperties.Name="Item 0 Image accessible name" Height="64" Width="64" HorizontalAlignment="Left" Source="Assets\Item0.png"/>
<Button Content="Add Item 0" Click="AddItem" CommandParameter="0"/>
<Button Content="Select Item 0" Click="SelectItem" CommandParameter="0"/>
<Button Content="Remove Item 0" Click="RemoveItem" CommandParameter="0"/>
<Slider x:Name="slider0" />
<ToggleSwitch x:Name="toggle0" />
<Slider AutomationProperties.Name="Item 0 Slider accessible name" x:Name="slider0" />
<ToggleSwitch x:Name="toggle0" AutomationProperties.Name="Item 0 ToggleSwitch accessible name" />
</StackPanel>
<StackPanel Style="{StaticResource ButtonGroup}">
<Image Height="64" Width="64" HorizontalAlignment="Left" Source="Assets\Item1.png"/>
<StackPanel AutomationProperties.Name="Item 1 details" Style="{StaticResource ButtonGroup}">
<Image AutomationProperties.Name="Item 1 Image accessible name" Height="64" Width="64" HorizontalAlignment="Left" Source="Assets\Item1.png"/>
<Button Content="Add Item 1" Click="AddItem" CommandParameter="1"/>
<Button Content="Select Item 1" Click="SelectItem" CommandParameter="1"/>
<Button Content="Remove Item 1" Click="RemoveItem" CommandParameter="1"/>
<Slider x:Name="slider1" />
<ToggleSwitch x:Name="toggle1" />
<Slider AutomationProperties.Name="Item 1 Slider accessible name" x:Name="slider1" />
<ToggleSwitch x:Name="toggle1" AutomationProperties.Name="Item 1 ToggleSwitch accessible name" />
</StackPanel>
<StackPanel Style="{StaticResource ButtonGroup}">
<Image Height="64" Width="64" HorizontalAlignment="Left" Source="Assets\Item2.png"/>
<StackPanel AutomationProperties.Name="Item 2 details" Style="{StaticResource ButtonGroup}">
<Image AutomationProperties.Name="Item 2 Image accessible name" Height="64" Width="64" HorizontalAlignment="Left" Source="Assets\Item2.png"/>
<Button Content="Add Item 2" Click="AddItem" CommandParameter="2"/>
<Button Content="Select Item 2" Click="SelectItem" CommandParameter="2"/>
<Button Content="Remove Item 2" Click="RemoveItem" CommandParameter="2"/>
<Slider x:Name="slider2" />
<ToggleSwitch x:Name="toggle2" />
<Slider AutomationProperties.Name="Item 2 Slider accessible name" x:Name="slider2" />
<ToggleSwitch x:Name="toggle2" AutomationProperties.Name="Item 2 ToggleSwitch accessible name" />
</StackPanel>
<StackPanel Style="{StaticResource ButtonGroup}">
<Image Height="64" Width="64" HorizontalAlignment="Left" Source="Assets\Item3.png"/>
<StackPanel AutomationProperties.Name="Item 3 details" Style="{StaticResource ButtonGroup}">
<Image AutomationProperties.Name="Item 3 Image accessible name" Height="64" Width="64" HorizontalAlignment="Left" Source="Assets\Item3.png"/>
<Button Content="Add Item 3" Click="AddItem" CommandParameter="3"/>
<Button Content="Select Item 3" Click="SelectItem" CommandParameter="3"/>
<Button Content="Remove Item 3" Click="RemoveItem" CommandParameter="3"/>
<Slider x:Name="slider3" />
<ToggleSwitch x:Name="toggle3" />
<Slider AutomationProperties.Name="Item 3 Slider accessible name" x:Name="slider3" />
<ToggleSwitch x:Name="toggle3" AutomationProperties.Name="Item 3 ToggleSwitch accessible name" />
</StackPanel>
<StackPanel Style="{StaticResource ButtonGroup}">
<TextBlock Height="64" Width="64" HorizontalAlignment="Left" FontFamily="Segoe UI Emoji" FontSize="45" Text="&#x2764;"/>
<!-- There's no guarantee that a symbolic character from some font will be pronounced by a screen reader
in a helpful way. So set helpful, concise, localized and uniqueaccessible names on the TextBlocks
so that a screen reader can make your customers aware of their purpose. This sample contains
placeholder text which would be replaced with appropriate localized text by a shipping app. -->
<StackPanel AutomationProperties.Name="Item 4 details" Style="{StaticResource ButtonGroup}">
<TextBlock AutomationProperties.Name="Item 4 TextBlock accessible name" Height="64" Width="64" HorizontalAlignment="Left" FontFamily="Segoe UI Emoji" FontSize="45" Text="&#x2764;"/>
<Button Content="Add Item 4" Click="AddItem" CommandParameter="4"/>
<Button Content="Select Item 4" Click="SelectItem" CommandParameter="4"/>
<Button Content="Remove Item 4" Click="RemoveItem" CommandParameter="4"/>
<Slider x:Name="slider4" />
<ToggleSwitch x:Name="toggle4" />
<Slider AutomationProperties.Name="Item 4 Slider accessible name" x:Name="slider4" />
<ToggleSwitch x:Name="toggle4" AutomationProperties.Name="Item 4 ToggleSwitch accessible name" />
</StackPanel>
<StackPanel Style="{StaticResource ButtonGroup}">
<TextBlock Height="64" Width="64" HorizontalAlignment="Left" FontFamily="Assets\fontawesome-webfont.ttf#FontAwesome" FontSize="57" Text="&#xf0a1;"/>
<StackPanel AutomationProperties.Name="Item 5 details" Style="{StaticResource ButtonGroup}">
<TextBlock AutomationProperties.Name="Item 5 TextBlock accessible name" Height="64" Width="64" HorizontalAlignment="Left" FontFamily="Assets\fontawesome-webfont.ttf#FontAwesome" FontSize="57" Text="&#xf0a1;"/>
<Button Content="Add Item 5" Click="AddItem" CommandParameter="5"/>
<Button Content="Select Item 5" Click="SelectItem" CommandParameter="5"/>
<Button Content="Remove Item 5" Click="RemoveItem" CommandParameter="5"/>
<Slider x:Name="slider5" />
<ToggleSwitch x:Name="toggle5" />
<Slider AutomationProperties.Name="Item 5 Slider accessible name" x:Name="slider5" />
<ToggleSwitch x:Name="toggle5" AutomationProperties.Name="Item 5 ToggleSwitch accessible name" />
</StackPanel>
</GridView>
@ -121,7 +137,7 @@
<StackPanel Style="{StaticResource PaddedPanel}">
<TextBlock FontSize="20">Log</TextBlock>
<ScrollViewer x:Name="logViewer" Grid.Column="0" MaxHeight="300" Padding="0,0,20,0">
<TextBlock x:Name="log" SizeChanged="OnLogSizeChanged"/>
<TextBlock x:Name="log" SizeChanged="OnLogSizeChanged" />
</ScrollViewer>
</StackPanel>
</StackPanel>

Просмотреть файл

@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
@ -39,5 +38,3 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -36,47 +36,58 @@
<ScrollViewer Grid.Row="1" VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">
<StackPanel Orientation="Vertical" VerticalAlignment="Top">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Text="Friendly Name" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<TextBox x:Name="FriendlyName" Text="My Virtual Smart Card" HorizontalAlignment="Left"/>
<TextBlock Name="FriendlyNameLabel" Text="Friendly Name" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<!-- Always give a TextBox a name that's accessible to a screen reader. In this case,
reference the labeling TextBlock to have the accessible name set on the TextBox. -->
<TextBox x:Name="FriendlyName" Text="My Virtual Smart Card" HorizontalAlignment="Left"
AutomationProperties.LabeledBy="{Binding ElementName=FriendlyNameLabel}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Text="Minimum PIN length" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<TextBox x:Name="PinMinLength" InputScope="Number" Text="8" HorizontalAlignment="Left"/>
<TextBlock Name="PinMinLengthLabel" Text="Minimum PIN length" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<TextBox x:Name="PinMinLength" InputScope="Number" Text="8" HorizontalAlignment="Left"
AutomationProperties.LabeledBy="{Binding ElementName=PinMinLengthLabel}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Text="Maximum PIN length" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<TextBox x:Name="PinMaxLength" InputScope="Number" Text="127" HorizontalAlignment="Left"/>
<TextBlock Name="PinMaxLengthLabel" Text="Maximum PIN length" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<TextBox x:Name="PinMaxLength" InputScope="Number" Text="127" HorizontalAlignment="Left"
AutomationProperties.LabeledBy="{Binding ElementName=PinMaxLengthLabel}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Text="Character Set" HorizontalAlignment="Left" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Text="Uppercase" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<ComboBox x:Name="PinUppercase" SelectedIndex="1" HorizontalAlignment="Left" VerticalAlignment="Center">
<TextBlock Name="PinUppercaseLabel" Text="Uppercase" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<!-- Always give a ComboBox a name that's accessible to a screen reader. In this case,
reference the labeling TextBlock to have the accessible name set on the ComboBox. -->
<ComboBox x:Name="PinUppercase" SelectedIndex="1" HorizontalAlignment="Left" VerticalAlignment="Center"
AutomationProperties.LabeledBy="{Binding ElementName=PinUppercaseLabel}">
<x:String>Disallowed</x:String>
<x:String>Allowed</x:String>
<x:String>Require At Least One</x:String>
</ComboBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Text="Lowercase" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<ComboBox x:Name="PinLowercase" SelectedIndex="1" HorizontalAlignment="Left" VerticalAlignment="Center">
<TextBlock Name="PinLowercaseLabel" Text="Lowercase" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<ComboBox x:Name="PinLowercase" SelectedIndex="1" HorizontalAlignment="Left" VerticalAlignment="Center"
AutomationProperties.LabeledBy="{Binding ElementName=PinLowercaseLabel}">
<x:String>Disallowed</x:String>
<x:String>Allowed</x:String>
<x:String>Require At Least One</x:String>
</ComboBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Text="Digits" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<ComboBox x:Name="PinDigits" SelectedIndex="1" HorizontalAlignment="Left" VerticalAlignment="Center">
<TextBlock Name="PinDigitsLabel" Text="Digits" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<ComboBox x:Name="PinDigits" SelectedIndex="1" HorizontalAlignment="Left" VerticalAlignment="Center"
AutomationProperties.LabeledBy="{Binding ElementName=PinDigitsLabel}">
<x:String>Disallowed</x:String>
<x:String>Allowed</x:String>
<x:String>Require At Least One</x:String>
</ComboBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Text="Special" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<ComboBox x:Name="PinSpecial" SelectedIndex="1" HorizontalAlignment="Left" VerticalAlignment="Center">
<TextBlock Name="PinSpecialLabel" Text="Special" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Width="85"/>
<ComboBox x:Name="PinSpecial" SelectedIndex="1" HorizontalAlignment="Left" VerticalAlignment="Center"
AutomationProperties.LabeledBy="{Binding ElementName=PinSpecialLabel}">
<x:String>Disallowed</x:String>
<x:String>Allowed</x:String>
<x:String>Require At Least One</x:String>

Просмотреть файл

@ -36,20 +36,27 @@
<Border x:Name="ErrorBorder" Background="Red" Grid.Row="2"/>
<TextBlock x:Name="StatusBlock" Grid.Row="2" Margin="12, 10, 12, 10" Visibility="Collapsed"/>
</Grid>
<Button Content="Play" Click="PlayButton_Click" HorizontalAlignment="Left" Margin="93,273,0,335" Width="47"/>
<Button Content="Stop" Click="StopButton_Click" HorizontalAlignment="Left" Margin="189,273,0,335" Width="50"/>
<Slider x:Name="RadiusSlider" HorizontalAlignment="Left" Margin="9,213,0,0" VerticalAlignment="Top" Width="152" Maximum="10" LargeChange="1" Value="1" ValueChanged="RadiusSlider_ValueChanged" SmallChange="0.1" TickFrequency="1" StepFrequency="0.1"/>
<ComboBox x:Name="EnvironmentComboBox" HorizontalAlignment="Left" Margin="9,100,0,0" VerticalAlignment="Top" Width="160" IsDropDownOpen="True" SelectionChanged="EnvironmentComboBox_SelectionChanged">
<!-- Always give ComboBoxes and Sliders names that are accessible to a screen reader.
In this case, reference the labeling TextBlocks to have the accessible names set
on the ComboBoxes and Sliders. -->
<TextBlock x:Name="textBlock1" HorizontalAlignment="Left" Margin="10,74,0,0" TextWrapping="Wrap" Text="Environment" VerticalAlignment="Top"/>
<ComboBox x:Name="EnvironmentComboBox" HorizontalAlignment="Left" Margin="9,100,0,0" VerticalAlignment="Top" Width="160" IsDropDownOpen="True" SelectionChanged="EnvironmentComboBox_SelectionChanged"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock1}">
<x:String>Small Room</x:String>
<x:String>Medium Room</x:String>
<x:String>Large Room</x:String>
<x:String>Outdoors</x:String>
</ComboBox>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="9,203,0,0" TextWrapping="Wrap" Text="Radius of Orbit" VerticalAlignment="Top"/>
<TextBlock x:Name="textBlock1" HorizontalAlignment="Left" Margin="10,74,0,0" TextWrapping="Wrap" Text="Environment" VerticalAlignment="Top"/>
<TextBlock x:Name="textBlock2" HorizontalAlignment="Left" Margin="9,149,0,0" TextWrapping="Wrap" Text="Speed of Orbit in Seconds" VerticalAlignment="Top"/>
<Slider x:Name="RotationSpeedSlider" HorizontalAlignment="Left" Margin="10,159,0,0" VerticalAlignment="Top" Width="152" Maximum="20" LargeChange="1" ValueChanged="RotationSpeedSlider_ValueChanged" SmallChange="0.5"/>
<Slider x:Name="HeightSlider" HorizontalAlignment="Left" Margin="191,213,0,0" VerticalAlignment="Top" Width="152" Minimum="-10" Maximum="10" LargeChange="1" SmallChange="0.5" ValueChanged="HeightSlider_ValueChanged"/>
<Slider x:Name="RotationSpeedSlider" HorizontalAlignment="Left" Margin="10,159,0,0" VerticalAlignment="Top" Width="152" Maximum="20" LargeChange="1" ValueChanged="RotationSpeedSlider_ValueChanged" SmallChange="0.5"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock2}"/>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="9,203,0,0" TextWrapping="Wrap" Text="Radius of Orbit" VerticalAlignment="Top"/>
<Slider x:Name="RadiusSlider" HorizontalAlignment="Left" Margin="9,213,0,0" VerticalAlignment="Top" Width="152" Maximum="10" LargeChange="1" Value="1" ValueChanged="RadiusSlider_ValueChanged" SmallChange="0.1" TickFrequency="1" StepFrequency="0.1"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock}"/>
<TextBlock x:Name="textBlock3" HorizontalAlignment="Left" Margin="191,203,0,0" TextWrapping="Wrap" Text="Height of Orbit" VerticalAlignment="Top"/>
<Slider x:Name="HeightSlider" HorizontalAlignment="Left" Margin="191,213,0,0" VerticalAlignment="Top" Width="152" Minimum="-10" Maximum="10" LargeChange="1" SmallChange="0.5" ValueChanged="HeightSlider_ValueChanged"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock3}"/>
<Button Content="Play" Click="PlayButton_Click" HorizontalAlignment="Left" Margin="93,273,0,335" Width="47"/>
<Button Content="Stop" Click="StopButton_Click" HorizontalAlignment="Left" Margin="189,273,0,335" Width="50"/>
</Grid>
</Page>

Просмотреть файл

@ -26,32 +26,47 @@
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="Description:" VerticalAlignment="Top" FontSize="26.667" Height="35" Width="140"/>
<TextBlock x:Name="textBlock1" HorizontalAlignment="Left" Margin="10,50,0,0" TextWrapping="Wrap" Text="Source with cardioid directivity pattern" VerticalAlignment="Top" FontSize="13.333" Height="18" Width="229"/>
<Slider x:Name="ScalingSlider" HorizontalAlignment="Left" Margin="10,177,0,0" VerticalAlignment="Top" Width="160" LargeChange="0.5" Maximum="1" SmallChange="0.1" StepFrequency="0.1" TickFrequency="0.1" Height="44" ValueChanged="ScalingSlider_ValueChanged" ToolTipService.ToolTip="0 is Omnidirectional and 1 is fully directional"/>
<Slider x:Name="OrderSlider" HorizontalAlignment="Left" Margin="189,177,0,0" VerticalAlignment="Top" Width="160" LargeChange="0.5" Maximum="32" SmallChange="0.1" StepFrequency="0.1" Minimum="0.1" Height="44" TickFrequency="0.1" ValueChanged="OrderSlider_ValudChanged" ToolTipService.ToolTip="Higher the order, narrower the directivity pattern"/>
<ComboBox x:Name="EnvironmentComboBox" HorizontalAlignment="Left" Margin="10,115,0,0" VerticalAlignment="Top" Width="160" SelectionChanged="EnvironmentComboBox_SelectionChanged" Height="28">
<!-- Always give ComboBoxes and Sliders names that are accessible to a screen reader.
In this case, reference the labeling TextBlocks to have the accessible names set
on the ComboBoxes and Sliders. -->
<TextBlock x:Name="textBlock4" HorizontalAlignment="Left" Margin="10,90,0,0" TextWrapping="Wrap" Text="Environment" VerticalAlignment="Top"/>
<ComboBox x:Name="EnvironmentComboBox" HorizontalAlignment="Left" Margin="10,115,0,0" VerticalAlignment="Top" Width="160" SelectionChanged="EnvironmentComboBox_SelectionChanged" Height="28"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock4}">
<x:String>Small Room</x:String>
<x:String>Medium Room</x:String>
<x:String>Large Room</x:String>
<x:String>Outdoors</x:String>
</ComboBox>
<Slider x:Name="YawSlider" HorizontalAlignment="Left" Margin="10,337,0,0" VerticalAlignment="Top" Width="100" Maximum="6.283185307" SmallChange="0.5" Height="44" ValueChanged="YawSlider_ValueChanged" LargeChange="0.5"/>
<Slider x:Name="PitchSlider" HorizontalAlignment="Left" Margin="120,337,0,0" VerticalAlignment="Top" Width="100" Maximum="6.283185307" SmallChange="0.5" Height="44" ValueChanged="PitchSlider_ValueChanged" LargeChange="0.5"/>
<Slider x:Name="RollSlider" HorizontalAlignment="Left" Margin="235,337,0,0" VerticalAlignment="Top" Width="100" Maximum="6.283185307" SmallChange="0.5" Height="44" ValueChanged="RollSlider_ValueChanged" LargeChange="0.5"/>
<Button x:Name="PlayButton" Content="Play" HorizontalAlignment="Left" Margin="93,396,0,0" VerticalAlignment="Top" Height="32" Width="47" Click="PlayButton_Click"/>
<Button x:Name="StopButton" Content="Stop" HorizontalAlignment="Left" Margin="189,396,0,0" VerticalAlignment="Top" Height="32" Width="50" Click="StopButton_Click"/>
<TextBlock x:Name="textBlock2" HorizontalAlignment="Left" Margin="10,164,0,0" TextWrapping="Wrap" Text="Directivity Scaling" VerticalAlignment="Top"/>
<Slider x:Name="ScalingSlider" HorizontalAlignment="Left" Margin="10,177,0,0" VerticalAlignment="Top" Width="160" LargeChange="0.5" Maximum="1" SmallChange="0.1" StepFrequency="0.1" TickFrequency="0.1" Height="44" ValueChanged="ScalingSlider_ValueChanged" ToolTipService.ToolTip="0 is Omnidirectional and 1 is fully directional"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock2}" />
<TextBlock x:Name="textBlock3" HorizontalAlignment="Left" Margin="189,164,0,0" TextWrapping="Wrap" Text="Cardioid Order" VerticalAlignment="Top"/>
<TextBlock x:Name="textBlock4" HorizontalAlignment="Left" Margin="10,90,0,0" TextWrapping="Wrap" Text="Environment" VerticalAlignment="Top"/>
<TextBlock x:Name="textBlock5" HorizontalAlignment="Left" Margin="10,326,0,0" TextWrapping="Wrap" Text="Yaw" VerticalAlignment="Top"/>
<TextBlock x:Name="textBlock6" HorizontalAlignment="Left" Margin="137,326,0,0" TextWrapping="Wrap" Text="Pitch" VerticalAlignment="Top"/>
<TextBlock x:Name="textBlock7" HorizontalAlignment="Left" Margin="250,326,0,0" TextWrapping="Wrap" Text="Roll" VerticalAlignment="Top"/>
<TextBlock x:Name="textBlock8" HorizontalAlignment="Left" Margin="10,300,0,0" TextWrapping="Wrap" Text="Source Orientation in Radians" VerticalAlignment="Top"/>
<Slider x:Name="OrderSlider" HorizontalAlignment="Left" Margin="189,177,0,0" VerticalAlignment="Top" Width="160"
LargeChange="0.5" Maximum="32" SmallChange="0.1" StepFrequency="0.1" Minimum="0.1" Height="44" TickFrequency="0.1"
ValueChanged="OrderSlider_ValudChanged"
ToolTipService.ToolTip="Higher the order, narrower the directivity pattern"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock3}" />
<TextBlock x:Name="textBlock9" HorizontalAlignment="Left" Margin="10,220,0,0" TextWrapping="Wrap" Text="Source Position in Meters" VerticalAlignment="Top"/>
<TextBlock x:Name="textBlock10" HorizontalAlignment="Left" Margin="10,252,0,364" TextWrapping="Wrap" Text="X:" VerticalAlignment="Center" Height="24" Width="25"/>
<Slider x:Name="SourcePositionXSlider" HorizontalAlignment="Left" Margin="30,244,0,0" VerticalAlignment="Top" Width="80" Height="44" Maximum="10" LargeChange="1" SmallChange="0.5" ValueChanged="SourcePositionX_ValueChanged" Minimum="-10"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock10}" />
<TextBlock x:Name="textBlock11" HorizontalAlignment="Left" Margin="126,253,0,0" TextWrapping="Wrap" Text="Y:" VerticalAlignment="Top" Width="27"/>
<Slider x:Name="SourcePositionYSlider" HorizontalAlignment="Left" Margin="149,244,0,0" VerticalAlignment="Top" Width="80" Height="44" Maximum="10" LargeChange="1" SmallChange="0.5" ValueChanged="SourcePositionY_ValueChanged" Minimum="-10"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock11}" />
<TextBlock x:Name="textBlock12" HorizontalAlignment="Left" Margin="250,253,0,0" TextWrapping="Wrap" Text="Z:" VerticalAlignment="Top"/>
<Slider x:Name="SourcePositionXSlider" HorizontalAlignment="Left" Margin="30,244,0,0" VerticalAlignment="Top" Width="80" Height="44" Maximum="10" LargeChange="1" SmallChange="0.5" ValueChanged="SourcePositionX_ValueChanged" Minimum="-10"/>
<Slider x:Name="SourcePositionYSlider" HorizontalAlignment="Left" Margin="149,244,0,0" VerticalAlignment="Top" Width="80" Height="44" Maximum="10" LargeChange="1" SmallChange="0.5" ValueChanged="SourcePositionY_ValueChanged" Minimum="-10"/>
<Slider x:Name="SourcePositionZSlider" HorizontalAlignment="Left" Margin="269,244,0,0" VerticalAlignment="Top" Width="80" Height="44" Maximum="10" LargeChange="1" SmallChange="0.5" ValueChanged="SourcePositionZ_ValueChanged" Minimum="-10"/>
<Slider x:Name="SourcePositionZSlider" HorizontalAlignment="Left" Margin="269,244,0,0" VerticalAlignment="Top" Width="80" Height="44" Maximum="10" LargeChange="1" SmallChange="0.5" ValueChanged="SourcePositionZ_ValueChanged" Minimum="-10"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock12}" />
<TextBlock x:Name="textBlock8" HorizontalAlignment="Left" Margin="10,300,0,0" TextWrapping="Wrap" Text="Source Orientation in Radians" VerticalAlignment="Top"/>
<TextBlock x:Name="textBlock5" HorizontalAlignment="Left" Margin="10,326,0,0" TextWrapping="Wrap" Text="Yaw" VerticalAlignment="Top"/>
<Slider x:Name="YawSlider" HorizontalAlignment="Left" Margin="10,337,0,0" VerticalAlignment="Top" Width="100" Maximum="6.283185307" SmallChange="0.5" Height="44" ValueChanged="YawSlider_ValueChanged" LargeChange="0.5"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock5}" />
<TextBlock x:Name="textBlock6" HorizontalAlignment="Left" Margin="137,326,0,0" TextWrapping="Wrap" Text="Pitch" VerticalAlignment="Top"/>
<Slider x:Name="PitchSlider" HorizontalAlignment="Left" Margin="120,337,0,0" VerticalAlignment="Top" Width="100" Maximum="6.283185307" SmallChange="0.5" Height="44" ValueChanged="PitchSlider_ValueChanged" LargeChange="0.5"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock6}" />
<TextBlock x:Name="textBlock7" HorizontalAlignment="Left" Margin="250,326,0,0" TextWrapping="Wrap" Text="Roll" VerticalAlignment="Top"/>
<Slider x:Name="RollSlider" HorizontalAlignment="Left" Margin="235,337,0,0" VerticalAlignment="Top" Width="100" Maximum="6.283185307" SmallChange="0.5" Height="44" ValueChanged="RollSlider_ValueChanged" LargeChange="0.5"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock7}" />
<Button x:Name="PlayButton" Content="Play" HorizontalAlignment="Left" Margin="93,396,0,0" VerticalAlignment="Top" Height="32" Width="47" Click="PlayButton_Click"/>
<Button x:Name="StopButton" Content="Stop" HorizontalAlignment="Left" Margin="189,396,0,0" VerticalAlignment="Top" Height="32" Width="50" Click="StopButton_Click"/>
</Grid>
</Page>

Просмотреть файл

@ -25,8 +25,12 @@
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="Description:" VerticalAlignment="Top" FontSize="26.667" Height="35" Width="140"/>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="10,50,0,0" TextWrapping="Wrap" Text="Source with custom decay" VerticalAlignment="Top" FontSize="13.333" Height="18" Width="229"/>
<!-- Always give ComboBoxes and Sliders names that are accessible to a screen reader.
In this case, reference the labeling TextBlocks to have the accessible names set
on the ComboBoxes and Sliders. -->
<TextBlock x:Name="textBlock4" HorizontalAlignment="Left" Margin="10,90,0,0" TextWrapping="Wrap" Text="HRTF Environment" VerticalAlignment="Top"/>
<ComboBox x:Name="EnvironmentComboBox" HorizontalAlignment="Left" Margin="10,115,0,0" VerticalAlignment="Top" Width="160" Height="28" SelectionChanged="EnvironmentComboBox_SelectionChanged">
<ComboBox x:Name="EnvironmentComboBox" HorizontalAlignment="Left" Margin="10,115,0,0" VerticalAlignment="Top" Width="160" Height="28" SelectionChanged="EnvironmentComboBox_SelectionChanged"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock4}">
<x:String>Small Room</x:String>
<x:String>Medium Room</x:String>
<x:String>Large Room</x:String>
@ -34,13 +38,16 @@
</ComboBox>
<TextBlock x:Name="textBlock9" HorizontalAlignment="Left" Margin="10,169,0,0" TextWrapping="Wrap" Text="Source Position in Meters" VerticalAlignment="Top"/>
<TextBlock x:Name="textBlock10" HorizontalAlignment="Left" Margin="10,201,0,415" TextWrapping="Wrap" Text="X:" VerticalAlignment="Center" Height="24" Width="25"/>
<Slider x:Name="SourcePositionXSlider" HorizontalAlignment="Left" Margin="30,193,0,0" VerticalAlignment="Top" Width="80" Height="44" Maximum="10" LargeChange="1" SmallChange="0.5" Minimum="-10" ValueChanged="SourcePositionX_ValueChanged"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock10}" />
<TextBlock x:Name="textBlock11" HorizontalAlignment="Left" Margin="126,202,0,0" TextWrapping="Wrap" Text="Y:" VerticalAlignment="Top" Width="27"/>
<Slider x:Name="SourcePositionYSlider" HorizontalAlignment="Left" Margin="149,193,0,0" VerticalAlignment="Top" Width="80" Height="44" Maximum="10" LargeChange="1" SmallChange="0.5" Minimum="-10" ValueChanged="SourcePositionY_ValueChanged"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock11}" />
<TextBlock x:Name="textBlock12" HorizontalAlignment="Left" Margin="250,202,0,0" TextWrapping="Wrap" Text="Z:" VerticalAlignment="Top"/>
<Slider x:Name="SourcePositionXSlider" HorizontalAlignment="Left" Margin="30,193,0,0" VerticalAlignment="Top" Width="80" Height="44" Maximum="10" LargeChange="1" SmallChange="0.5" Minimum="-10" ValueChanged="SourcePositionX_ValueChanged"/>
<Slider x:Name="SourcePositionYSlider" HorizontalAlignment="Left" Margin="149,193,0,0" VerticalAlignment="Top" Width="80" Height="44" Maximum="10" LargeChange="1" SmallChange="0.5" Minimum="-10" ValueChanged="SourcePositionY_ValueChanged"/>
<Slider x:Name="SourcePositionZSlider" HorizontalAlignment="Left" Margin="269,193,0,0" VerticalAlignment="Top" Width="80" Height="44" Maximum="10" LargeChange="1" SmallChange="0.5" Minimum="-10" ValueChanged="SourcePositionZ_ValueChanged"/>
<Slider x:Name="SourcePositionZSlider" HorizontalAlignment="Left" Margin="269,193,0,0" VerticalAlignment="Top" Width="80" Height="44" Maximum="10" LargeChange="1" SmallChange="0.5" Minimum="-10" ValueChanged="SourcePositionZ_ValueChanged"
AutomationProperties.LabeledBy="{Binding ElementName=textBlock12}" />
<Button x:Name="PlayButton" Content="Play" HorizontalAlignment="Left" Margin="93,252,0,0" VerticalAlignment="Top" Height="32" Width="47" Click="PlayButton_Click"/>
<Button x:Name="StopButton" Content="Stop" HorizontalAlignment="Left" Margin="189,252,0,0" VerticalAlignment="Top" Height="32" Width="50" Click="StopButton_Click"/>
</Grid>
</Page>

Просмотреть файл

@ -11,7 +11,7 @@
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.15063.0</TargetPlatformMinVersion>
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
<FileAlignment>512</FileAlignment>

Просмотреть файл

@ -1,50 +0,0 @@
<!--
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
-->
<Page
x:Class="SDKTemplate.Scenario1_CheckConsentAvailability"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SDKTemplate"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="RootGrid" Margin="12,20,12,12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Margin="0,0,0,10">
<TextBlock Text="Description:" Style="{StaticResource SampleHeaderTextStyle}"/>
<TextBlock Style="{StaticResource ScenarioDescriptionTextStyle}" TextWrapping="Wrap">
Verifies the availability of fingerprint consent.
</TextBlock>
</StackPanel>
<ScrollViewer Grid.Row="1" VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">
<StackPanel Orientation="Vertical" VerticalAlignment="Top">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0" Grid.Row="1">
<Button x:Name="CheckAvailability" Content="Check Availability" Margin="0,0,10,0" Click="CheckAvailability_Click"/>
</StackPanel>
</StackPanel>
</ScrollViewer>
<!-- Status Block for providing messages to the user. Use the
NotifyUser() method to populate the message -->
<Border x:Name="ErrorBorder" Background="Red" Grid.Row="2"/>
<TextBlock x:Name="StatusBlock" Grid.Row="2" Margin="12, 10, 12, 10" Visibility="Collapsed"/>
</Grid>
</Grid>
</Page>

Просмотреть файл

@ -7,16 +7,8 @@ using namespace SDKTemplate;
using namespace concurrency;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Security::Credentials::UI;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
Scenario1_CheckConsentAvailability::Scenario1_CheckConsentAvailability()
{
@ -24,42 +16,28 @@ Scenario1_CheckConsentAvailability::Scenario1_CheckConsentAvailability()
}
// Check the availability of Windows Hello authentication through User Consent Verifier.
void Scenario1_CheckConsentAvailability::CheckAvailability_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
void Scenario1_CheckConsentAvailability::CheckAvailability_Click(Object^ sender, RoutedEventArgs^ e)
{
Button^ checkAvailabilityButton = dynamic_cast<Button^>(sender);
checkAvailabilityButton->IsEnabled = false;
CheckAvailabilityButton->IsEnabled = false;
try
create_task(UserConsentVerifier::CheckAvailabilityAsync())
.then([this](UserConsentVerifierAvailability consentAvailability)
{
create_task(Windows::Security::Credentials::UI::UserConsentVerifier::CheckAvailabilityAsync())
.then([checkAvailabilityButton](UserConsentVerifierAvailability consentAvailability)
switch (consentAvailability)
{
switch (consentAvailability)
{
case UserConsentVerifierAvailability::Available:
{
MainPage::Current->NotifyUser("User consent verification available!", NotifyType::StatusMessage);
break;
}
case UserConsentVerifierAvailability::Available:
MainPage::Current->NotifyUser("User consent verification is available.", NotifyType::StatusMessage);
break;
case UserConsentVerifierAvailability::DeviceNotPresent:
{
MainPage::Current->NotifyUser("No PIN or biometric found, please set one up.", NotifyType::ErrorMessage);
break;
}
case UserConsentVerifierAvailability::DeviceNotPresent:
MainPage::Current->NotifyUser("No PIN or biometric device found, please set one up.", NotifyType::ErrorMessage);
break;
default:
{
MainPage::Current->NotifyUser("User consent verification is currently unavailable.", NotifyType::ErrorMessage);
break;
}
}
checkAvailabilityButton->IsEnabled = true;
});
}
catch (Exception ^ex)
{
MainPage::Current->NotifyUser("Checking the availability of Consent feature failed with exception. Operation: CheckAvailabilityAsync, Exception: " + ex->ToString(), NotifyType::ErrorMessage);
checkAvailabilityButton->IsEnabled = true;
}
default:
MainPage::Current->NotifyUser("User consent verification is currently unavailable.", NotifyType::ErrorMessage);
break;
}
CheckAvailabilityButton->IsEnabled = true;
});
}

Просмотреть файл

@ -1,55 +0,0 @@
<!--
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
-->
<Page
x:Class="SDKTemplate.Scenario2_RequestConsent"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SDKTemplate"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="RootGrid" Margin="12,20,12,12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Margin="0,0,0,10">
<TextBlock Text="Description:" Style="{StaticResource SampleHeaderTextStyle}"/>
<TextBlock Style="{StaticResource ScenarioDescriptionTextStyle}" TextWrapping="Wrap">
Requests fingerprint consent from the current user. Allows the calling application to specify a message to display.
</TextBlock>
</StackPanel>
<ScrollViewer Grid.Row="1" VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">
<StackPanel Orientation="Vertical" VerticalAlignment="Top">
<!-- Add Content Here -->
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Text="Message:" VerticalAlignment="Center" Width="85"/>
<TextBox x:Name="Message" Text="Message to user" Width="300"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Button x:Name="RequestConsent" Content="Request Consent" Margin="85,0,0,0" Click="RequestConsent_Click"/>
</StackPanel>
</StackPanel>
</ScrollViewer>
<!-- Status Block for providing messages to the user. Use the
NotifyUser() method to populate the message -->
<Border x:Name="ErrorBorder" Background="Red" Grid.Row="2"/>
<TextBlock x:Name="StatusBlock" Grid.Row="2" Margin="12, 10, 12, 10" Visibility="Collapsed"/>
</Grid>
</Grid>
</Page>

Просмотреть файл

@ -7,16 +7,8 @@ using namespace SDKTemplate;
using namespace concurrency;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Security::Credentials::UI;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
Scenario2_RequestConsent::Scenario2_RequestConsent()
{
@ -24,58 +16,33 @@ Scenario2_RequestConsent::Scenario2_RequestConsent()
}
// Requests consent from the current user.
void Scenario2_RequestConsent::RequestConsent_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
void Scenario2_RequestConsent::RequestConsent_Click(Object^ sender, RoutedEventArgs^ e)
{
Button^ requestConsentButton = dynamic_cast<Button^>(sender);
requestConsentButton->IsEnabled = false;
RequestConsentButton->IsEnabled = false;
// Read the message that has to be displayed in the consent request prompt
if (Message->Text != nullptr)
// Request the user's consent using Windows Hello via biometric verification or a PIN.
String^ message = L"Please confirm your identity to complete this (pretend) in-app purchase.";
create_task(Windows::Security::Credentials::UI::UserConsentVerifier::RequestVerificationAsync(message))
.then([this](UserConsentVerificationResult consentResult)
{
try
switch (consentResult)
{
// Request the logged on user's consent using Windows Hello via biometric verification or a PIN.
create_task(Windows::Security::Credentials::UI::UserConsentVerifier::RequestVerificationAsync(Message->Text))
.then([requestConsentButton](UserConsentVerificationResult consentResult)
{
switch (consentResult)
{
case UserConsentVerificationResult::Verified:
{
MainPage::Current->NotifyUser("User consent verified!", NotifyType::StatusMessage);
break;
}
case UserConsentVerificationResult::Verified:
MainPage::Current->NotifyUser("Pretend in-app purchase was successful.", NotifyType::StatusMessage);
break;
case UserConsentVerificationResult::DeviceNotPresent:
{
MainPage::Current->NotifyUser("No PIN or biometric found, please set one up.", NotifyType::ErrorMessage);
break;
}
case UserConsentVerificationResult::DeviceNotPresent:
MainPage::Current->NotifyUser("No PIN or biometric device found, please set one up.", NotifyType::ErrorMessage);
break;
case UserConsentVerificationResult::Canceled:
{
MainPage::Current->NotifyUser("User consent verification canceled.", NotifyType::ErrorMessage);
break;
}
case UserConsentVerificationResult::Canceled:
MainPage::Current->NotifyUser("User consent verification canceled.", NotifyType::ErrorMessage);
break;
default:
{
MainPage::Current->NotifyUser("User consent verification is currently unavailable.", NotifyType::ErrorMessage);
break;
}
}
requestConsentButton->IsEnabled = true;
});
default:
MainPage::Current->NotifyUser("User consent verification is currently unavailable.", NotifyType::ErrorMessage);
break;
}
catch (Exception ^ex)
{
MainPage::Current->NotifyUser("Request current user's consent failed with exception. Operation: RequestVerificationAsync, Exception: " + ex->ToString(), NotifyType::ErrorMessage);
requestConsentButton->IsEnabled = true;
}
}
else
{
MainPage::Current->NotifyUser("Empty Message String. Enter prompt string in the Message text field.", NotifyType::ErrorMessage);
requestConsentButton->IsEnabled = true;
}
}
RequestConsentButton->IsEnabled = true;
});
}

Просмотреть файл

@ -155,10 +155,10 @@
</ClInclude>
<ClInclude Include="SampleConfiguration.h" />
<ClInclude Include="Scenario1_CheckConsentAvailability.xaml.h">
<DependentUpon>Scenario1_CheckConsentAvailability.xaml</DependentUpon>
<DependentUpon>..\shared\Scenario1_CheckConsentAvailability.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="Scenario2_RequestConsent.xaml.h">
<DependentUpon>Scenario2_RequestConsent.xaml</DependentUpon>
<DependentUpon>..\shared\Scenario2_RequestConsent.xaml</DependentUpon>
</ClInclude>
</ItemGroup>
<ItemGroup>
@ -168,8 +168,8 @@
<Page Include="..\..\..\SharedContent\cpp\MainPage.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="Scenario1_CheckConsentAvailability.xaml" />
<Page Include="Scenario2_RequestConsent.xaml" />
<Page Include="..\shared\Scenario1_CheckConsentAvailability.xaml" />
<Page Include="..\shared\Scenario2_RequestConsent.xaml" />
<Page Include="..\..\..\SharedContent\xaml\Styles.xaml">
<Link>Styles\Styles.xaml</Link>
</Page>
@ -196,10 +196,10 @@
</ClCompile>
<ClCompile Include="SampleConfiguration.cpp" />
<ClCompile Include="Scenario1_CheckConsentAvailability.xaml.cpp">
<DependentUpon>Scenario1_CheckConsentAvailability.xaml</DependentUpon>
<DependentUpon>..\shared\Scenario1_CheckConsentAvailability.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="Scenario2_RequestConsent.xaml.cpp">
<DependentUpon>Scenario2_RequestConsent.xaml</DependentUpon>
<DependentUpon>..\shared\Scenario2_RequestConsent.xaml</DependentUpon>
</ClCompile>
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -47,8 +47,8 @@
</ItemGroup>
<ItemGroup>
<Page Include="..\..\..\SharedContent\cpp\MainPage.xaml" />
<Page Include="Scenario1_CheckConsentAvailability.xaml" />
<Page Include="Scenario2_RequestConsent.xaml" />
<Page Include="..\shared\Scenario1_CheckConsentAvailability.xaml" />
<Page Include="..\shared\Scenario2_RequestConsent.xaml" />
<Page Include="..\..\..\SharedContent\xaml\Styles.xaml">
<Filter>Styles</Filter>
</Page>

Просмотреть файл

@ -12,7 +12,6 @@
using System;
using System.Collections.Generic;
using Windows.UI.Xaml.Controls;
using UserConsentVerifier;
namespace SDKTemplate
{

Просмотреть файл

@ -1,50 +0,0 @@
<!--
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
-->
<Page
x:Class="UserConsentVerifier.Scenario1_CheckConsentAvailability"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UserConsentVerifier"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="RootGrid" Margin="12,20,12,12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Margin="0,0,0,10">
<TextBlock Text="Description:" Style="{StaticResource SampleHeaderTextStyle}"/>
<TextBlock Style="{StaticResource ScenarioDescriptionTextStyle}" TextWrapping="Wrap">
Verifies the availability of fingerprint consent.
</TextBlock>
</StackPanel>
<ScrollViewer Grid.Row="1" VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">
<StackPanel Orientation="Vertical" VerticalAlignment="Top">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0" Grid.Row="1">
<Button x:Name="CheckAvailability" Content="Check Availability" Margin="0,0,10,0" Click="CheckAvailability_Click"/>
</StackPanel>
</StackPanel>
</ScrollViewer>
<!-- Status Block for providing messages to the user. Use the
NotifyUser() method to populate the message -->
<Border x:Name="ErrorBorder" Background="Red" Grid.Row="2"/>
<TextBlock x:Name="StatusBlock" Grid.Row="2" Margin="12, 10, 12, 10" Visibility="Collapsed"/>
</Grid>
</Grid>
</Page>

Просмотреть файл

@ -14,9 +14,8 @@ using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Windows.Security.Credentials.UI;
using System;
using SDKTemplate;
namespace UserConsentVerifier
namespace SDKTemplate
{
public sealed partial class Scenario1_CheckConsentAvailability : Page
{
@ -27,48 +26,29 @@ namespace UserConsentVerifier
this.InitializeComponent();
}
/// <summary>
/// This is the click handler for the 'Check Availability' button. It checks the availability of Windows Hello via User Consent Verifier
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void CheckAvailability_Click(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
b.IsEnabled = false;
try
{
// Check the availability of Windows Hello authentication through User Consent Verifier.
UserConsentVerifierAvailability consentAvailability = await Windows.Security.Credentials.UI.UserConsentVerifier.CheckAvailabilityAsync();
switch (consentAvailability)
{
case UserConsentVerifierAvailability.Available:
{
rootPage.NotifyUser("User consent verification available!", NotifyType.StatusMessage);
break;
}
CheckAvailabilityButton.IsEnabled = false;
case UserConsentVerifierAvailability.DeviceNotPresent:
{
rootPage.NotifyUser("No PIN or biometric found, please set one up.", NotifyType.ErrorMessage);
break;
}
// Check the availability of Windows Hello authentication through User Consent Verifier.
UserConsentVerifierAvailability consentAvailability = await UserConsentVerifier.CheckAvailabilityAsync();
switch (consentAvailability)
{
case UserConsentVerifierAvailability.Available:
rootPage.NotifyUser("User consent verification available!", NotifyType.StatusMessage);
break;
default:
{
rootPage.NotifyUser("User consent verification is currently unavailable.", NotifyType.ErrorMessage);
break;
}
}
}
catch (Exception ex)
{
rootPage.NotifyUser("Checking the availability of Consent feature failed with exception. Operation: CheckAvailabilityAsync, Exception: " + ex.ToString(), NotifyType.ErrorMessage);
}
finally
{
b.IsEnabled = true;
case UserConsentVerifierAvailability.DeviceNotPresent:
rootPage.NotifyUser("No PIN or biometric found, please set one up.", NotifyType.ErrorMessage);
break;
default:
rootPage.NotifyUser("User consent verification is currently unavailable.", NotifyType.ErrorMessage);
break;
}
CheckAvailabilityButton.IsEnabled = true;
}
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше