2010-07-20 17 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消息。我不能說我對這個解決方案太高興了,但它似乎工作。