使用System.Window.Forms.Form的MFC对话框显示新对话框,在其上调用Control.Visible.set(bool值)并冻结

时间:2016-01-25 11:02:59

标签: winforms mfc modal-dialog freeze

Windows.Forms.Form + MFC CDialog freeze

在我们的应用程序中,我们在从MFC CDialog继承的对话框上调用DoModal(),在这个模式对话框中,我们显示了一些使用System.Windows.Forms的第三方内容,这个内容创建了新的System.Windows.Forms.Form,当它在Form上调用ShowDialog(),新对话框全部显示为白色并冻结。新对话框挂在_NtWaitForSingleObject中,我不知道为什么以及做什么。

我们的应用程序中的ShowDialog()调用(冻结):

ntdll.dll!_NtWaitForSingleObject@12()  + 0x15 bytes 
KernelBase.dll!_WaitForSingleObjectEx@12()  + 0x98 bytes    
kernel32.dll!_WaitForSingleObjectExImplementation@12()  + 0x43 bytes    
user32.dll!_InternalCallWinProc@20()  + 0x23 bytes  
user32.dll!_UserCallWinProcCheckWow@32()  + 0xb7 bytes  
user32.dll!_DispatchClientMessage@24()  + 0x51 bytes    
user32.dll!___fnDWORDOPTINLPMSG@4()  + 0x35 bytes   
ntdll.dll!_KiUserCallbackDispatcher@12()  + 0x2e bytes  
user32.dll!_NtUserMessageCall@28()  + 0x15 bytes    
user32.dll!_SendMessageWorker@24()  + 0x8c15 bytes  
user32.dll!_SendMessageW@16()  + 0x4c bytes 
user32.dll!_xxxRemoveDefaultButton@16()  + 0x56 bytes   
user32.dll!_xxxSaveDlgFocus@8()  + 0x4a bytes   
user32.dll!_DefDlgProcWorker@24()  + 0x196d bytes   
user32.dll!_DefDlgProcW@16()  + 0x29 bytes  
user32.dll!_InternalCallWinProc@20()  + 0x23 bytes  
user32.dll!_UserCallWinProcCheckWow@32()  + 0xb7 bytes  
user32.dll!_CallWindowProcAorW@24()  + 0x5e bytes   
user32.dll!_CallWindowProcW@20()  + 0x1b bytes  
mfc100u.dll!CWnd::DefWindowProcW()  + 0x44 bytes    
mfc100u.dll!CWnd::WindowProc()  + 0x3b bytes    
mfc100u.dll!AfxCallWndProc()  + 0xb5 bytes  
mfc100u.dll!AfxWndProc()  + 0x37 bytes  
mfc100u.dll!AfxWndProcBase()  + 0x56 bytes  
user32.dll!_InternalCallWinProc@20()  + 0x23 bytes  
user32.dll!_UserCallWinProcCheckWow@32()  + 0xb7 bytes  
user32.dll!_DispatchClientMessage@24()  + 0x51 bytes    
user32.dll!___fnDWORD@4()  + 0x2b bytes 
ntdll.dll!_KiUserCallbackDispatcher@12()  + 0x2e bytes  
user32.dll!_NtUserShowWindow@8()  + 0x15 bytes  
[Managed to Native Transition]  
System.Windows.Forms.dll!System.Windows.Forms.Control.SetVisibleCore(bool value = true) + 0x402 bytes   
System.Windows.Forms.dll!System.Windows.Forms.Form.SetVisibleCore(bool value = true) + 0x88 bytes   
System.Windows.Forms.dll!System.Windows.Forms.Control.Visible.set(bool value) + 0x16 bytes  
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = 4, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.Application.ModalApplicationContext}) + 0x1a2 bytes 
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x4c bytes    
System.Windows.Forms.dll!System.Windows.Forms.Application.RunDialog(System.Windows.Forms.Form form) + 0x33 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) + 0x329 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog() + 0xc bytes 

ShowDialog()在专用应用程序中的调用(不冻结):

[Managed to Native Transition]  
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason = 4, int pvLoopData = 0) + 0x577 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = 4, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.Application.ModalApplicationContext}) + 0x1bc bytes 
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x55 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) + 0x432 bytes    

因此在冻结情况下,调用Control.Visible.set(bool值)并且在非冻结情况下,ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID,int reason = 4 ,int pvLoopData = 0)被调用。为什么呢?

我试图搜索并发现人们有类似的冻结问题,并使用属性[STAThread]或SetApartmentState(ApartmentState.STA)修复它,但我不确定这是否是相同的情况,主应用程序是在C ++,而不是C#。所有这些对话创建都出现在我们的主线程中,该主线程是使用CWinAppEx :: Run()创建的。

会发生什么,如何正确优雅地解决冻结?

0 个答案:

没有答案