#include "interop-exception.h" #include #include #include using namespace System; using namespace System::Collections::Generic; struct device_info { std::wstring name; std::wstring id; }; std::vector get_unique_device_info() { std::vector info; rawinput_foreach_with_interface([&](const auto& dev, const WCHAR* name) { info.push_back({ L"", // get_property_wstr(name, &DEVPKEY_Device_FriendlyName), /* doesn't work */ dev_id_from_interface(name) }); }); std::sort(info.begin(), info.end(), [](auto&& l, auto&& r) { return l.id < r.id; }); auto last = std::unique(info.begin(), info.end(), [](auto&& l, auto&& r) { return l.id == r.id; }); info.erase(last, info.end()); return info; } public ref struct RawInputInterop { static void AddHandlesFromID(String^ deviceID, List^ rawInputHandles) { try { std::vector nativeHandles = rawinput_handles_from_dev_id( msclr::interop::marshal_as(deviceID)); for (auto nh : nativeHandles) rawInputHandles->Add(IntPtr(nh)); } catch (const std::exception& e) { throw gcnew RawInputInteropException(e); } } static List>^ GetDeviceIDs() { try { auto managed = gcnew List>(); for (auto&& [name, id] : get_unique_device_info()) { managed->Add( ValueTuple( msclr::interop::marshal_as(name), msclr::interop::marshal_as(id))); } return managed; } catch (const std::exception& e) { throw gcnew RawInputInteropException(e); } } };