Add winui3 test sample

This commit is contained in:
Eugene Wang
2026-01-08 22:25:13 -05:00
committed by GitHub
parent b4f16ca417
commit f47be8f1f7
11 changed files with 408 additions and 1 deletions

View File

@@ -1,5 +1,6 @@
<Solution>
<Configurations>
<Platform Name="ARM64" />
<Platform Name="x64" />
<Platform Name="x86" />
</Configurations>
@@ -20,11 +21,19 @@
<Project Path="samples/KodakTester/KodakTester.csproj" />
<Project Path="samples/WinForm32/WinForm32.csproj" />
<Project Path="samples/WinForm64/WinForm64.csproj" />
<Project Path="samples/WinUI3/WinUI3.csproj" Id="9876f110-22e9-4813-8f5d-b317c152885f">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
<Platform Solution="*|x86" Project="x86" />
</Project>
<Project Path="samples\ConsoleSample\ConsoleSample.csproj">
<Platform Solution="*|ARM64" Project="x64" />
<Platform Solution="*|x64" Project="x64" />
<Platform Solution="*|x86" Project="x86" />
</Project>
</Folder>
<Project Path="csizes\csizes.vcxproj" Id="1aabd2dc-3f81-4301-938b-3ec2edef38d4" />
<Project Path="csizes\csizes.vcxproj" Id="1aabd2dc-3f81-4301-938b-3ec2edef38d4">
<Platform Solution="*|ARM64" Project="x64" />
</Project>
<Project Path="src\NTwain\NTwain.csproj" />
</Solution>

16
samples/WinUI3/App.xaml Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Application
x:Class="WinUI3.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinUI3">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@@ -0,0 +1,48 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.UI.Xaml.Shapes;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace WinUI3;
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public partial class App : Application
{
private Window? _window;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
InitializeComponent();
}
/// <summary>
/// Invoked when the application is launched.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
_window = new MainWindow();
_window.Activate();
}
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="WinUI3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinUI3"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="WinUI3">
<Window.SystemBackdrop>
<MicaBackdrop />
</Window.SystemBackdrop>
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button x:Name="testButton" Click="testButton_Click">Test Scan!</Button>
</StackPanel>
</Grid>
</Window>

View File

@@ -0,0 +1,150 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using NTwain;
using NTwain.Data;
using NTwain.Events;
using System;
using System.Diagnostics;
using System.IO;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace WinUI3;
/// <summary>
/// An empty window that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainWindow : Window
{
TwainAppSession session;
readonly uint _jpegQuality = 85;
readonly string saveFolder;
readonly Stopwatch watch = new();
public MainWindow()
{
InitializeComponent();
var libVer = FileVersionInfo.GetVersionInfo(typeof(TwainAppSession).Assembly.Location).ProductVersion;
Title = $"WinUI3 sample {(Environment.Is64BitProcess ? " 64bit" : " 32bit")} on NTwain {libVer}";
saveFolder = Path.Combine(Path.GetTempPath(), "ntwain-sample" + Path.DirectorySeparatorChar);
Directory.CreateDirectory(saveFolder);
session = new TwainAppSession();
session.StateChanged += Session_StateChanged;
session.SourceDisabled += Session_SourceDisabled;
session.TransferReady += Session_TransferReady;
session.Transferred += Session_Transferred;
session.TransferError += Session_TransferError;
this.Closed += MainWindow_Closed;
}
private void testButton_Click(object sender, RoutedEventArgs e)
{
if (session.State < STATE.S3)
session.OpenDsm();
if (session.ShowUserSelect().IsSuccess)
{
if (session.OpenSource(session.DefaultSource!).IsSuccess)
{
if (session.EnableSource(SourceEnableOption.ShowUI).IsSuccess)
{
watch.Restart();
}
}
}
}
private void Session_TransferError(TwainAppSession sender, TransferErrorEventArgs e)
{
if (e.Exception != null)
{
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] transfer error {e.Exception}.");
}
else
{
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] transfer error {e.Code}.");
}
}
private void MainWindow_Closed(object sender, WindowEventArgs args)
{
session.TryStepdown(STATE.S2);
session.Dispose();
}
private void Session_TransferReady(TwainAppSession sender, TransferReadyEventArgs e)
{
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] transfer ready.");
}
private void Session_Transferred(TwainAppSession sender, TransferredEventArgs e)
{
try
{
// example of using some lib to handle image data
var saveFile = Path.Combine(saveFolder, (DateTime.Now.Ticks / 1000).ToString());
if (e.Data != null)
{
using var img = new ImageMagick.MagickImage(e.Data.AsSpan());
var format = ImageMagick.MagickFormat.Png;
if (img.ColorType == ImageMagick.ColorType.Palette)
{
// bw or gray
saveFile += ".png";
}
else
{
// color
saveFile += ".jpg";
format = ImageMagick.MagickFormat.Jpeg;
img.Quality = _jpegQuality;
}
img.Write(saveFile, format);
Debug.WriteLine($"Saved image to {saveFile}");
}
}
catch { }
finally
{
e.Dispose();
}
}
private void Session_SourceDisabled(TwainAppSession sender, TWIdentityWrapper e)
{
session.CloseSource();
if (watch.IsRunning)
{
watch.Stop();
var dlg = new ContentDialog
{
Title = "Completed",
Content = $"Took {watch.Elapsed} to finish that transfer.",
CloseButtonText = "OK",
XamlRoot = Content.XamlRoot
};
_ = dlg.ShowAsync();
try
{
if (Directory.Exists(saveFolder))
{
using (Process.Start(new ProcessStartInfo { FileName = saveFolder, UseShellExecute = true })) { }
}
}
catch { }
}
}
private void Session_StateChanged(TwainAppSession sender, STATE e)
{
}
}

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="aa6cdc62-8d2a-45fb-b810-529d3b928630"
Publisher="CN=yinch"
Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="aa6cdc62-8d2a-45fb-b810-529d3b928630" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>WinUI3</DisplayName>
<PublisherDisplayName>yinch</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="WinUI3"
Description="WinUI3"
BackgroundColor="transparent"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Platform>ARM64</Platform>
<RuntimeIdentifier>win-arm64</RuntimeIdentifier>
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Platform>x64</Platform>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Platform>x86</Platform>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RootNamespace>WinUI3</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x86;x64;ARM64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
<UseWinUI>true</UseWinUI>
<WinUISDKReferences>false</WinUISDKReferences>
<Nullable>enable</Nullable>
<WindowsPackageType>None</WindowsPackageType>
</PropertyGroup>
<ItemGroup>
<Manifest Include="$(ApplicationManifest)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Magick.NET-Q8-x86" Version="14.10.1" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.7463" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.251106002" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NTwain\NTwain.csproj" />
</ItemGroup>
<!-- Publish Properties -->
<PropertyGroup>
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="WinUI3.app"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- The ID below informs the system that this application is compatible with OS features first introduced in Windows 10.
It is necessary to support features in unpackaged applications, for example the custom titlebar implementation.
For more info see https://docs.microsoft.com/windows/apps/windows-app-sdk/use-windows-app-sdk-run-time#declare-os-compatibility-in-your-application-manifest -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>