Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions src/WinUIEx/Share.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;

using Windows.ApplicationModel.DataTransfer;

namespace WinUIEx
{
// https://learn.microsoft.com/en-us/windows/apps/develop/windows-integration/integrate-sharesheet-send#implement-share-for-desktop-apps-winui-3-wpf-winforms

[System.Runtime.InteropServices.ComImport]
[System.Runtime.InteropServices.Guid("3A3DCD6C-3EAB-43DC-BCDE-45671CE800C8")]
[System.Runtime.InteropServices.InterfaceType(
System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIUnknown)]
interface IDataTransferManagerInterop
{
IntPtr GetForWindow([System.Runtime.InteropServices.In] IntPtr appWindow,
[System.Runtime.InteropServices.In] ref Guid riid);
void ShowShareUIForWindow(IntPtr appWindow);
}

public partial class WindowEx
Comment thread
dotMorten marked this conversation as resolved.
Outdated
{
private DataTransferManager? _dtm;

// Call this from your window or form constructor (or load handler):
private void InitializeShare()
{
// Retrieve the window handle (HWND) for the current window:
// WinUI 3: IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
// WPF: IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
// WinForms: IntPtr hWnd = this.Handle;
IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);

IDataTransferManagerInterop interop =
DataTransferManager.As<IDataTransferManagerInterop>();

// IID of DataTransferManager, passed as the riid to GetForWindow:
Guid dtmIid = new(0xa5caee9b, 0x8708, 0x49d1, 0x8d, 0x36, 0x67, 0xd2, 0x5a, 0x8d, 0xa0, 0x0c);
_dtm = WinRT.MarshalInterface<DataTransferManager>.FromAbi(interop.GetForWindow(hWnd, dtmIid));

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be done on-the-fly in the extension method and cleaned up after instead?

@AkazaRenn AkazaRenn Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After ab23884, it is done on-the-fly, please see #275 (comment).

}

/// <summary>
/// Displays the Windows Share UI for this window and supplies the specified
/// <see cref="DataPackage"/> when the user completes the share operation.
/// </summary>
/// <param name="data">
/// The data package to share. This is provided to the Share UI when the
/// <c>DataRequested</c> event is raised.
/// </param>
/// <exception cref="InvalidOperationException">
/// Thrown if <see cref="InitializeShare"/> has not been called before invoking this method.
/// </exception>
public void Share(DataPackage data)
{
if (_dtm is null)
{
throw new InvalidOperationException("Share has not been initialized. Call InitializeShare() first.");
}

void handler(DataTransferManager sender, DataRequestedEventArgs args)
{
args.Request.Data = data;
if (_dtm is not null) {
_dtm.DataRequested -= handler;
}
}

_dtm.DataRequested += handler;
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
var interop = DataTransferManager.As<IDataTransferManagerInterop>();
interop.ShowShareUIForWindow(hWnd);
}
}
}
2 changes: 2 additions & 0 deletions src/WinUIEx/WindowEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public WindowEx()
Grid.SetRow(windowArea, 1);
rootContent.Children.Add(windowArea);

InitializeShare();

this.Content = rootContent;
}

Expand Down
1 change: 1 addition & 0 deletions src/WinUIExSample/Pages/Dialogs.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<Button Content="Show dialog" Click="ShowDialog_Click" />
<Button Content="Show OK/Cancel" Click="ShowDialog2_Click" />
<Button Content="Show 3-option dialog" Click="ShowDialog3_Click" />
<Button Content="Show share sheet" Click="ShowShareSheet_Click" />
<TextBlock x:Name="resultText" />
</StackPanel>
</Grid>
Expand Down
12 changes: 11 additions & 1 deletion src/WinUIExSample/Pages/Dialogs.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,20 @@ private async void ShowDialog3_Click(object sender, RoutedEventArgs e)
new Windows.UI.Popups.UICommand("Blue Pill"),
new Windows.UI.Popups.UICommand("Cancel")
};
string message = "This is your last chance. After this, there is no turning back. You take the blue pill the story ends, you wake up in your bed and believe whatever you want to believe. You take the red pill you stay in Wonderland, and I show you how deep the rabbit hole goes. Remember, all I'm offering is the truth nothing more.";
string message = "This is your last chance. After this, there is no turning back. You take the blue pill � the story ends, you wake up in your bed and believe whatever you want to believe. You take the red pill � you stay in Wonderland, and I show you how deep the rabbit hole goes. Remember, all I'm offering is the truth � nothing more.";
Comment thread
dotMorten marked this conversation as resolved.
Outdated
var result = await MainWindow.ShowMessageDialogAsync(message, commands, cancelCommandIndex: 2, title: "Morpheus Asks");
resultText.Text = "You chose: " + result.Label;
}

private async void ShowShareSheet_Click(object sender, RoutedEventArgs e)
{
resultText.Text = "";
var data = new Windows.ApplicationModel.DataTransfer.DataPackage();
data.Properties.Title = "WinUIEx Sample Share";
data.SetUri(new Uri("https://github.com/dotMorten/WinUIEx"));
data.SetText("Hello from WinUIEx!");
MainWindow.Share(data);
}

}
}
Loading