Skip to content

Instantly share code, notes, and snippets.

@smourier
Created December 24, 2022 15:45
Show Gist options
  • Save smourier/5904014c5ba1bf5e92d417eafd11e63a to your computer and use it in GitHub Desktop.
Save smourier/5904014c5ba1bf5e92d417eafd11e63a to your computer and use it in GitHub Desktop.
Shows Windows' "Modern Share" UI in a standard desktop Win32 app.
#include <Windows.h>
#include <ShObjIdl_core.h>
#include <windows.applicationmodel.datatransfer.h> // for the IIDs (ABI namespace)
#include <winrt/windows.applicationmodel.datatransfer.h>
#include <winrt/windows.foundation.collections.h>
#include <winrt/windows.storage.h>
// compile at least with ISO C++20 Standard (/std:c++20)
using namespace winrt;
using namespace winrt::Windows::ApplicationModel::DataTransfer;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Storage;
IAsyncAction OnDataRequested(DataTransferManager const& sender, DataRequestedEventArgs const& args)
{
auto referral = args.Request().GetDeferral(); // see https://learn.microsoft.com/en-us/uwp/api/windows.applicationmodel.datatransfer.datarequest.getdeferral?view=winrt-22621#remarks
auto data = args.Request().Data();
// get a storage item
auto file = co_await StorageFile::GetFileFromPathAsync(L"d:\\temp\\zzz.txt");
// build a collection with it and assign to data
auto items{ single_threaded_vector<IStorageItem>() };
items.Append(file);
data.SetStorageItems(items.GetView());
// set title & description
data.Properties().Title(file.Name());
data.Properties().Description(L"This item will be shared.");
referral.Complete(); // commit
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_LBUTTONDOWN:
{
// get a IDataTransferManagerInterop reference so we can work with an HWND
// as we're a regular Win32 desktop app
auto dtmi = get_activation_factory<DataTransferManager, IDataTransferManagerInterop>();
// DataTransferManager Class "Programmatically initiates an exchange of content with other apps."
// https://learn.microsoft.com/en-us/uwp/api/windows.applicationmodel.datatransfer.datatransfermanager
DataTransferManager dtm{ nullptr };
check_hresult(dtmi->GetForWindow(hwnd, __uuidof(ABI::Windows::ApplicationModel::DataTransfer::IDataTransferManager), put_abi(dtm)));
// hook on event (when dtm asks us for data)
dtm.DataRequested(OnDataRequested);
// show the UI
check_hresult(dtmi->ShowShareUIForWindow(hwnd));
}
break;
case WM_CREATE:
SetWindowText(hwnd, L"Click somewhere");
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE, _In_ LPWSTR, _In_ int nCmdShow)
{
WNDCLASSEXW wc = {};
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"MyClass";
RegisterClassExW(&wc);
auto hwnd = CreateWindowW(L"MyClass", L"Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 700, nullptr, nullptr, hInstance, nullptr);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
@smourier
Copy link
Author

Displays this:

ModernShare

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment