private void DrawDXContent(DXContentType dxContentType, SwapChainPanelInteropBase scpBase, float[] color, Rect?rect) { switch (dxContentType) { case DXContentType.D2DTiles: scpBase.UpdateSurfaceWithD2DTiles(); break; case DXContentType.D3DClear: scpBase.UpdateSurface(color); break; case DXContentType.D2DClear: scpBase.UpdateSurfaceWithD2D(color); break; case DXContentType.D2DClock: scpBase.UpdateSurfaceWithD2DClock(color); break; case DXContentType.D2DRectangle: scpBase.UpdateSurfaceWithD2DRectangle(color, rect.HasValue ? rect.Value : new Rect()); break; default: throw new InvalidOperationException("Cannot draw this dx content type " + dxContentType.ToString()); } }
private SwapChainPanelInterop CreateSCPContent(ElementCompositeMode compositeMode, DXContentType dxContentType, float[] color, Rect?rect, int height = 200) { double scpWidth = scrollViewer.Width; double scpHeight = height; SwapChainPanel scp = new SwapChainPanel() { Width = scpWidth, Height = scpHeight, CompositeMode = compositeMode }; SwapChainPanelInterop scpInterop = scp; IDXGISwapChain1 swapChain = DXInteropHelper.CreateSwapChainForComposition(d3d11Device, (int)scpWidth, (int)scpHeight, false); scpInterop.SetSwapChain(swapChain); DrawDXContent(dxContentType, scpInterop, color, rect); scpInterop.CopyBuffers(1, 0); float compositionScaleX = 1; float compositionScaleY = 1; scp.CompositionScaleChanged += (s, e) => { compositionScaleX = scp.CompositionScaleX; compositionScaleY = scp.CompositionScaleY; try { scpInterop.ResizeBuffers((int)scp.Width, (int)scp.Height); } catch (System.Runtime.InteropServices.COMException ex) { if (ex.HResult == unchecked ((int)0x887A0005)) /* DXGI_ERROR_DEVICE_REMOVED */ { swapChain = DXInteropHelper.CreateSwapChainForComposition(d3d11Device, (int)scp.Width, (int)scp.Height, false); scpInterop.SetSwapChain(swapChain); } else { throw ex; } } DrawDXContent(dxContentType, scpInterop, color, rect); scpInterop.CopyBuffers(1, 0); }; StackPanel scpStackPanel = new StackPanel() { Orientation = Orientation.Vertical }; StackPanel sp = new StackPanel() { Orientation = Orientation.Horizontal }; TextBox scpWidthTB = new TextBox() { Height = 60, Header = "SCPWidth" }; TextBox scpHeightTB = new TextBox() { Height = 60, Header = "SCPHeight" }; Binding binding = new Binding() { Source = scp, Path = new PropertyPath("Width"), Mode = BindingMode.TwoWay }; scpWidthTB.SetBinding(TextBox.TextProperty, binding); binding = new Binding() { Source = scp, Path = new PropertyPath("Height"), Mode = BindingMode.TwoWay }; scpHeightTB.SetBinding(TextBox.TextProperty, binding); sp.Children.Add(scpWidthTB); sp.Children.Add(scpHeightTB); scpStackPanel.Children.Add(sp); StackPanel sp1 = new StackPanel() { Orientation = Orientation.Horizontal }; sp1.Children.Add(new TextBlock() { Text = "CoreInput" }); CheckBox coreinputEnabledCB = new CheckBox() { IsChecked = true, IsThreeState = false }; sp1.Children.Add(coreinputEnabledCB); sp1.Children.Add(new TextBlock() { Text = "Touch" }); CheckBox coreinputTouchCB = new CheckBox() { IsChecked = true, IsThreeState = false }; sp1.Children.Add(coreinputTouchCB); sp1.Children.Add(new TextBlock() { Text = "Mouse" }); CheckBox coreinputMouseCB = new CheckBox() { IsChecked = true, IsThreeState = false }; sp1.Children.Add(coreinputMouseCB); scpStackPanel.Children.Add(sp1); scp.Children.Add(scpStackPanel); bool enableTouchCoreInput = true; bool enableMouseCoreInput = true; CoreDispatcher coreInputDispatcher = null; CoreDispatcher xamlDispatcher = Window.Current.Dispatcher; Action coreInputThreadAction = () => { CoreInputDeviceTypes deviceTypes = CoreInputDeviceTypes.Pen; if (enableTouchCoreInput) { deviceTypes |= CoreInputDeviceTypes.Touch; } if (enableMouseCoreInput) { deviceTypes |= CoreInputDeviceTypes.Mouse; } CoreIndependentInputSource coreInput = scp.CreateCoreIndependentInputSource(deviceTypes); coreInputDispatcher = coreInput.Dispatcher; xamlDispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { coreinputEnabledCB.Unchecked += (s4, e4) => { coreInputDispatcher.RunAsync(CoreDispatcherPriority.High, () => { coreInput.IsInputEnabled = false; }); }; coreinputEnabledCB.Checked += (s4, e4) => { coreInputDispatcher.RunAsync(CoreDispatcherPriority.High, () => { coreInput.IsInputEnabled = true; }); }; }); coreInput.PointerPressed += (s, e) => { scpInterop.UpdateSurfaceWithD2DEllipse(new Point(e.CurrentPoint.Position.X * compositionScaleX, e.CurrentPoint.Position.Y * compositionScaleY), 10.0f, new float[] { 1f, 0f, 1f, 1f }, true /*copyBuffers*/); }; coreInput.PointerMoved += (s1, e1) => { scpInterop.UpdateSurfaceWithD2DEllipse(new Point(e1.CurrentPoint.Position.X * compositionScaleX, e1.CurrentPoint.Position.Y * compositionScaleY), 10.0f, new float[] { 0f, 0f, 1f, 1f }, true /*copyBuffers*/); }; coreInput.PointerReleased += (s2, e2) => { scpInterop.UpdateSurfaceWithD2DEllipse(new Point(e2.CurrentPoint.Position.X * compositionScaleX, e2.CurrentPoint.Position.Y * compositionScaleY), 10.0f, new float[] { 0f, 0f, 1f, 1f }, true /*copyBuffers*/); // Marking this unhandled so that AppBar can be invoked by letting the right click go through CoreInput which then raises WM_ContextMenu // that calls handles in xaml framework which marshalles the call to the UIthread to toggle AppBar. e2.Handled = false; }; coreInputDispatcher.ProcessEvents(CoreProcessEventsOption.ProcessUntilQuit); }; Action startCoreInputThread = () => { Windows.System.Threading.ThreadPool.RunAsync((asyncAction) => { if (coreInputDispatcher != null) { coreInputDispatcher.StopProcessEvents(); coreInputDispatcher = null; } coreInputThreadAction(); }, WorkItemPriority.High); }; startCoreInputThread(); coreinputTouchCB.Checked += (x, y) => { enableTouchCoreInput = true; startCoreInputThread(); }; coreinputTouchCB.Unchecked += (x, y) => { enableTouchCoreInput = false; startCoreInputThread(); }; coreinputMouseCB.Checked += (x, y) => { enableMouseCoreInput = true; scp.CompositeMode = (ElementCompositeMode)(((int)scp.CompositeMode + 1) % 4); startCoreInputThread(); }; coreinputMouseCB.Unchecked += (x, y) => { enableMouseCoreInput = false; startCoreInputThread(); }; return(scpInterop); }