I am trying to work my way through converting the 2nd SlimDX tutorial to Vb.Net and am having some trouble. I slightly changed the tutorial in the sense that I am creating a display class that inherits from the RenderForm Class. But I am getting an InvalidOperationException in the MessagePump.Run() function. The error message says "Starting a second message loop on a single thread is not a valid operation. Use Form.ShowDialog instead." I will just post the whole code becasue its only 70 lines or so.
This is the DisplayClass:
[source lang="vb"]Imports SlimDX.WindowsImports SlimDX.Direct3D11Imports SlimDX.DXGIImports SlimDXImports Device = SlimDX.Direct3D11.DeviceImports Resource = SlimDX.Direct3D11.ResourcePublic Class BaseStimulusDisplay Inherits RenderForm Protected device As Device = Nothing Protected swapChain As SwapChain = Nothing Protected renderTarget As RenderTargetView Protected context As DeviceContext Protected viewport As Viewport Public Sub New() Dim description As New SwapChainDescription() With description .BufferCount = 1 .Usage = Usage.RenderTargetOutput .OutputHandle = Me.Handle .IsWindowed = True .ModeDescription = New ModeDescription(0, 0, New Rational(60, 1), Format.B8G8R8A8_UNorm) .SampleDescription = New SampleDescription(1, 0) .Flags = SwapChainFlags.AllowModeSwitch .SwapEffect = SwapEffect.Discard End With 'Create the device with the SwapChain if I am haveing trouble debuging code. I might want to try to use the other ' device creation flags such as the debug flag device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, description, device, swapChain) Using resource As Texture2D = SlimDX.Direct3D11.Resource.FromSwapChain(Of Texture2D)(swapChain, 0) renderTarget = New RenderTargetView(device, resource) End Using context = device.ImmediateContext viewport = New Viewport(0.0F, 0.0F, Me.ClientSize.Width, Me.ClientSize.Height) context.OutputMerger.SetTargets(renderTarget) context.Rasterizer.SetViewports(viewport) Using factory As Factory = swapChain.GetParent(Of Factory)() factory.SetWindowAssociation(Me.Handle, WindowAssociationFlags.IgnoreAltEnter) End Using End Sub Private Sub toggleFullscreen(ByVal sender As System.Object, ByVal args As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown If args.Alt And args.KeyCode = Keys.Enter Then swapChain.IsFullScreen = Not swapChain.IsFullScreen End If End Sub Private Sub displayLoop() context.ClearRenderTargetView(renderTarget, New Color4(0.5F, 0.5F, 1.0F)) swapChain.Present(0, PresentFlags.None) End Sub Public Sub run() MessagePump.Run(Me, AddressOf displayLoop) End Sub Public Overloads Sub Dispose() swapChain.Dispose() renderTarget.Dispose() device.Dispose() MyBase.Dispose() End SubEnd Class[/source]
And this is the main startup form of my code:
[source lang="vb"]Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim form As New BaseStimulusDisplay() form.run() End SubEnd Class[/source]
As the error indicates, you should only start up the message pump once. This is the same mechanism as doing Application.Run(), which presumably you're calling at the start of your program to launch your form. The MessagePump.Run method is meant to be a substitute for this system.
Ok, So I set the BaseStimulusDisplay object as the start-up object/form and got rid of the other form all together which made the code work. I also called the .run method (which runs the messagePump() at the end of the constructor. That made the program run as I wanted however I want to be able to start and stop these "SlimDX windows" from a regular Visual Basic Form Application. How would I do this if the SlimDX messagePump and the form messagePump are mutually exclusive?