Currently I'm trying to develop a solution uses .Net Core 3.1 and it's responsible to select multiple capture windows, to be shared when focused.
I've made it work using a list, but I think would be much more elegant and user friendly if I've a picker that shows a preview of the window before selecting.
I'm trying to use GraphicsCapturePicker but I'm getting the following error:
The application called an interface that was marshalled for a different thread
Here is the following methods that I'm using to open the picker:
public async void OpenCapturePicker(object sender, RoutedEventArgs e)
{
Console.WriteLine("OpenCapturePicker");
await Dispatcher.InvokeAsync(OpenCapturePicker);
}
private async void OpenCapturePicker()
{
var picker = new GraphicsCapturePicker();
picker.SetWindow(_capturableWindowHandle);
var item = await picker.PickSingleItemAsync();
if (item == null) return;
//rest of code
}
The _capturableWindowHandle is defined in the constructor of the class like:
public SomeClass(){
_capturableWindowHandle = new WindowInteropHelper(this).Handle;
}
Also I've an extension class that allows me to use the SetWindow method
public static class CaptureHelper
{
static readonly Guid GraphicsCaptureItemGuid = new Guid("79C3F95B-31F7-4EC2-A464-632EF5D30760");
public static GraphicsCaptureItem CreateItemForWindow(IntPtr windowInteropHandler)
{
var factory = WindowsRuntimeMarshal.GetActivationFactory(typeof(GraphicsCaptureItem));
var interop = (IGraphicsCaptureItemInterop) factory;
var itemPointer = interop.CreateForWindow(windowInteropHandler, GraphicsCaptureItemGuid);
var item = Marshal.GetObjectForIUnknown(itemPointer) as GraphicsCaptureItem;
Marshal.Release(itemPointer);
return item;
}
public static void SetWindow(this GraphicsCapturePicker picker, IntPtr hwnd)
{
var interop = (IInitializeWithWindow)(object)picker;
interop.Initialize(hwnd);
}
}
Update
Here is the link of the branch that I'm using to add this feature
Any ideas?
CodePudding user response:
Update:
This Code worked for me:
if (!GraphicsCaptureSession.IsSupported()) {
Trace.WriteLine("No Capture Support");
return;
}
// var picker = new GraphicsCapturePicker();
// picker.SetWindow(_capturableWindowHandle);
// var item = await picker.PickSingleItemAsync();
var interopWindow = new WindowInteropHelper(this);
var hwnd = interopWindow.Handle;
var picker = new GraphicsCapturePicker();
picker.SetWindow(hwnd);
var item = await picker.PickSingleItemAsync();
if (item == null) {
return;
}
_windowCaptureService.StartCapture(item, _capturableWindowHandle);
Be aware: This code is not doing anything if you put a breakpoint in it... Maybe it is initialized with the debugger window in this case...??? But without breakpoints it is working on my Windows 10 machine.
First Answer:
The error message is telling you, that something was created on a different thread than it is used later on. I don't see your complete code here, but you should check, if you e.g. call the constructor of SomeClass in the same thread as
picker.SetWindow(_capturableWindowHandle);
Same thing with all other code involved here or prior to OpenCapturePicker...