【发布时间】:2017-08-16 13:07:59
【问题描述】:
我有一个问题一周以来无法解决,我希望有人能遇到过这种情况。
我正在将 SharpDX 与 windows 窗体项目一起使用,基本上有一个带有图片框和一些面板的窗体。
当我缩放或翻译图像时,典型的 Swapchain.Present(1,PresentFlags.None) 效果很好。但是,我遇到了这种奇怪的情况,当我最小化屏幕并重新打开它时,所有交换链内容都被隐藏起来,就像它已被删除一样。但是,我知道它没有,这可能是 GDI 刷新和 SharpDX 之间的竞争条件。
所以,我尝试在每个控件中覆盖 WndProc(Message m) 并处理它的绘制和擦除背景事件。这是行不通的。当我调试时,windows消息总是不时不同,所以很难找出可能是什么问题。
如果有人在 Windows 窗体上混合 SharpDX(或 directX)时遇到过这种行为,我真的很想得到答案。
这是我如何处理 SharpDX DeviceContext 的调整大小事件
Public Overrides Sub Resize(Width As Integer, Height As Integer)
If m_SwapChain IsNot Nothing Then
If m_BackBuffer IsNot Nothing Then
m_BackBuffer.Dispose()
End If
If m_2DDeviceContext IsNot Nothing Then
m_2DDeviceContext.Dispose()
End If
If m_2DTarget IsNot Nothing Then
m_2DTarget.Dispose()
End If
m_SwapChain.ResizeBuffers(2, Width, Height, Format.B8G8R8A8_UNorm, SwapChainFlags.GdiCompatible)
m_BackBuffer = m_SwapChain.GetBackBuffer(Of Surface)(0)
m_2DDeviceContext = New SharpDX.Direct2D1.DeviceContext(m_2DDevice, SharpDX.Direct2D1.DeviceContextOptions.EnableMultithreadedOptimizations)
m_2DTarget = New SharpDX.Direct2D1.Bitmap(m_2DDeviceContext, m_BackBuffer, m_Properties)
m_2DDeviceContext.AntialiasMode = AntialiasMode.PerPrimitive
m_2DDeviceContext.Target = m_2DTarget
CType(m_Context, GPUDrawingContext).DeviceContext = m_2DDeviceContext
End If
End Sub
编辑: 在尝试了很多东西之后,当我调用 base.Wndproc(m) where m = WM_PAINT 时,我意识到它正在发生。
我不能忽略绘制消息,因为如果我这样做了,我的控件仍然无效,它会在事件队列中添加一个新的 WM_PAINT 并将我发送到一个无限循环。我真的不能做 base.Wndproc(m) 因为这是我的交换链隐藏的地方。
他们是否有任何方法来处理(忽略)此事件消息而无需将其重新置于循环中,因为 SharpDX 不需要此功能,因为它是控件上的油漆层。
【问题讨论】:
-
你能展示一些代码吗(特别是你如何处理调整大小事件)?否则很难猜出发生了什么。
-
我编辑了我的帖子以添加我如何处理来自 SharpDX 的 deviceContext 大小调整,但我不确定这是否是您想要看到的。 (我不认为这来自它)
-
我确实记得最小化将大小设置为 0 的情况(并且尝试创建任何大小组件为零的交换链当然会带来各种问题)。我最终会首先检查这种情况(而不是在那种情况下重建交换链)。
-
此外,您最终应该确保在表单最小化时什么都不做(例如,不执行任何绘图/演示调用)。这在主循环开始时很容易做到(通过检查表单标志)。
-
除了所有的windows事件消息外,最小化没有做任何事情。此外,我的课程用于两个项目(两个窗口形式)我只在一个项目中遇到这个问题,而在另一个项目中没有。所以我最好的选择可能是因为这个项目有孩子,因为另一个没有?图片框的孩子可以刷新图片框以删除我的内容吗?
标签: c# winforms directx sharpdx