2010-07-20 39 views
0

我已经继承了当前正在从其CView::OnBeginPrinting重写中查询ADODB数据库的程序的维护。但是,当ADODB数据库句柄是进程外数据库连接的代理时,它经常崩溃 - 显然,在等待RPC响应时,绘制消息导致它重新输入CView的呈现处理,导致事情变得非常困惑。在CView中使用COM RPC :: OnBeginPrinting

有没有一种方法可以安全地使用来自CView::OnBeginPrinting的过程对象的COM?例如,如果我能阻止窗口消息有问题的窗口,直到COM调用完成,这可能会工作...

这里就是断言发生的堆栈跟踪:

mfc100d.dll!CPreviewDC::ReleaseOutputDC() Line 138 C++ (asserts here) 
mfc100d.dll!CPreviewView::OnDraw(CDC * pDC) Line 801 C++ 
mfc100d.dll!CView::OnPaint() Line 189 C++ 
mfc100d.dll!CWnd::OnWndMsg(unsigned int message, unsigned int wParam, long lParam, long * pResult) Line 2354 C++ 
mfc100d.dll!CWnd::WindowProc(unsigned int message, unsigned int wParam, long lParam) Line 2067 + 0x20 bytes C++ 
mfc100d.dll!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 248 + 0x1c bytes C++ 
mfc100d.dll!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 411 C++ 
mfc100d.dll!AfxWndProcBase(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 420 + 0x15 bytes C++ 
[email protected]() + 0x28 bytes 
[email protected]() + 0xa2 bytes 
[email protected]() + 0x4b bytes  
[email protected]() + 0x24 bytes 
[email protected]() + 0x2e bytes 
[email protected]() + 0xc bytes 
[email protected]() + 0xf bytes 
mfc100d.dll!COleMessageFilter::OnMessagePending(const tagMSG * __formal) Line 114 C++ 
mfc100d.dll!COleMessageFilter::XMessageFilter::MessagePending(HTASK__ * htaskCallee, unsigned long dwTickCount, unsigned long __formal) Line 312 C++ 
ole32.dll!CCliModalLoop::HandlePendingMessage() + 0x91de bytes 
ole32.dll!CCliModalLoop::HandleWakeForMsg() + 0x46 bytes 
ole32.dll!CCliModalLoop::BlockFn() - 0x34d92 bytes 
ole32.dll!ModalLoop() + 0x5b bytes 
ole32.dll!ThreadSendReceive() + 0x36c bytes  
ole32.dll!CRpcChannelBuffer::SwitchAptAndDispatchCall() + 0x4d bytes 
ole32.dll!CRpcChannelBuffer::SendReceive2() + 0x8d bytes 
ole32.dll!CCliModalLoop::SendReceive() + 0x1e bytes  
ole32.dll!CAptRpcChnl::SendReceive() + 0x1a25 bytes  
ole32.dll!CCtxComChnl::SendReceive() + 0x47 bytes 
[email protected]() + 0x40 bytes 
rpcrt4.dll!_NdrClientCall2() - 0xa83 bytes 
[email protected]() + 0x5d bytes 
[email protected]() + 0xf bytes 
ole32.dll!CStdMarshal::Begin_RemQIAndUnmarshal1() + 0x91 bytes 
ole32.dll!CStdMarshal::Begin_QueryRemoteInterfaces() + 0x46 bytes 
ole32.dll!CStdMarshal::QueryRemoteInterfaces() + 0x37 bytes  
ole32.dll!CStdIdentity::CInternalUnk::QueryMultipleInterfaces() - 0x2adf0 bytes  
ole32.dll!CStdIdentity::CInternalUnk::QueryInterface() + 0x30 bytes  
[email protected]() + 0x16 bytes  
jscript.dll!VAR::SetHeapObject() + 0x31 bytes 
jscript.dll!VAR::Import() + 0x45d bytes  
jscript.dll!VarList::ImportVar() + 0x2e bytes 
jscript.dll!VarList::ImportRgvar() - 0x160fb bytes 
jscript.dll!CSession::Execute() + 0xd6 bytes 
jscript.dll!NameTbl::InvokeDef() + 0x146 bytes 
jscript.dll!NameTbl::InvokeEx() - 0x42f bytes 
jscript.dll!IDispatchExInvokeEx2() + 0x8e bytes  
jscript.dll!IDispatchExInvokeEx() + 0x4f bytes 
jscript.dll!NameTbl::InvokeEx() - 0x18653 bytes  
msscript.ocx!CScriptControl::ModuleRun() + 0x171 bytes 
msscript.ocx!CScriptControl::Run() + 0x5d bytes  
[several levels of my code, which I cannot reveal] 
myapp.exe!MyView::OnBeginPrinting(CDC * pDC, CPrintInfo * pInfo) Line 92 C++ 
mfc100d.dll!CPreviewView::SetPrintView(CView * pPrintView) Line 370 C++ 
mfc100d.dll!CView::DoPrintPreview(unsigned int nIDResource, CView * pPrintView, CRuntimeClass * pPreviewViewClass, CPrintPreviewState * pState) Line 218 + 0xc bytes C++ 
mfc100d.dll!AFXPrintPreview(CView * pView) Line 298 + 0x1b bytes C++ 
+0

您是否真的看到该方法重新进入? – sharptooth 2010-07-20 08:38:11

+0

'OnBeginPrinting'本身不会被重新输入,但它会进入'CPreviewView :: OnDraw',然后由于'm_hDC'为空而在'CPreviewDC :: ReleaseOutputDC'中声明。 – bdonlan 2010-07-20 16:18:12

回答

0

在最后,我最终从012re中描述的CPreviewView派生出来,并在我忙于执行RPC时抑制WM_DRAW消息。我不能说我对这个解决方案太高兴了,但它似乎工作。