From: sb on
I'm trying to get to the bottom of this assert in wincore.cpp:

// should also be in the permanent or temporary handle map
CHandleMap* pMap = afxMapHWND();
ASSERT(pMap != NULL);

The comments say "it is likely that you have passed a C++ object from
one thread to another and have used that object in a way that was not
intended."


Here are the top frames from the main thread:

ntdll.dll!_KiFastSystemCallRet@0()
ntdll.dll!_ZwWaitForSingleObject(a)12() + 0xc bytes
kernel32.dll!_WaitForSingleObjectEx(a)12() + 0x8b bytes
kernel32.dll!_WaitForSingleObject@8() + 0x12 bytes
ole32.dll!GetToSTA() + 0x4e bytes
ole32.dll!CRpcChannelBuffer::SwitchAptAndDispatchCall() + 0xccf
bytes
ole32.dll!CRpcChannelBuffer::SendReceive2() + 0x76 bytes
ole32.dll!CAptRpcChnl::SendReceive() + 0x46 bytes
ole32.dll!CCtxComChnl::SendReceive() + 0x43 bytes
rpcrt4.dll!_NdrProxySendReceive@8() + 0x40 bytes
rpcrt4.dll!_NdrClientCall2() + 0x9dc bytes
rpcrt4.dll!_ObjectStublessClient@8() + 0x5d bytes
rpcrt4.dll!_ObjectStubless@0() + 0xf bytes
> mfc80d.dll!COleControlSite::DoVerb(long nVerb=-5, tagMSG * lpMsg=0x00000000) Line 740 C++
mfc80d.dll!COleControlSite::CreateControlCommon(CWnd *
pWndCtrl=0x00111504, const _GUID & clsid={...}, const
CControlCreationInfo & creationInfo={...}, const char *
lpszWindowName=0x00000000, unsigned long dwStyle=1342177280, const
tagPOINT * ppt=0x0010e878, const tagSIZE * psize=0x0010e870, unsigned
int nID=102, CFile * pPersist=0x00000000, int bStorage=0, wchar_t *
bstrLicKey=0x00000000) Line 280 + 0x11 bytes C++
mfc80d.dll!COleControlSite::CreateControl(CWnd * pWndCtrl=0x00111504,
const _GUID & clsid={...}, const char * lpszWindowName=0x00000000,
unsigned long dwStyle=1342177280, const tagPOINT * ppt=0x0010e878,
const tagSIZE * psize=0x0010e870, unsigned int nID=102, CFile *
pPersist=0x00000000, int bStorage=0, wchar_t * bstrLicKey=0x00000000)
Line 191 C++
mfc80d.dll!COleControlContainer::CreateControlCommon(CWnd *
pWndCtrl=0x00111504, const _GUID & clsid={...}, const
CControlCreationInfo & creationInfo={...}, const char *
lpszWindowName=0x00000000, unsigned long dwStyle=1342177280, const
tagPOINT * ppt=0x0010e878, const tagSIZE * psize=0x0010e870, unsigned
int nID=102, CFile * pPersist=0x00000000, int bStorage=0, wchar_t *
bstrLicKey=0x00000000, COleControlSite * * ppNewSite=0x00000000) Line
306 + 0x35 bytes C++
mfc80d.dll!COleControlContainer::CreateControl(CWnd *
pWndCtrl=0x00111504, const _GUID & clsid={...}, const char *
lpszWindowName=0x00000000, unsigned long dwStyle=1342177280, const
tagPOINT * ppt=0x0010e878, const tagSIZE * psize=0x0010e870, unsigned
int nID=102, CFile * pPersist=0x00000000, int bStorage=0, wchar_t *
bstrLicKey=0x00000000, COleControlSite * * ppNewSite=0x00000000) Line
342 C++
mfc80d.dll!CWnd::CreateControl(const _GUID & clsid={...}, const char
* lpszWindowName=0x00000000, unsigned long dwStyle=1342177280, const
tagPOINT * ppt=0x0010e878, const tagSIZE * psize=0x0010e870, CWnd *
pParentWnd=0x00111468, unsigned int nID=102, CFile *
pPersist=0x00000000, int bStorage=0, wchar_t * bstrLicKey=0x00000000)
Line 71 C++
mfc80d.dll!CWnd::CreateControl(const _GUID & clsid={...}, const char
* lpszWindowName=0x00000000, unsigned long dwStyle=1342177280, const
tagRECT & rect={...}, CWnd * pParentWnd=0x00111468, unsigned int
nID=102, CFile * pPersist=0x00000000, int bStorage=0, wchar_t *
bstrLicKey=0x00000000) Line 50 C++
mfc80d.dll!CDHtmlDialog::OnInitDialog() Line 942 C++
mfc80d.dll!AfxDlgProc(HWND__ * hWnd=0x000d0d24, unsigned int
message=272, unsigned int __formal=855332, unsigned int
__formal=855332) Line 28 + 0x10 bytes C++
user32.dll!_InternalCallWinProc(a)20() + 0x28 bytes
user32.dll!_UserCallDlgProcCheckWow(a)32() + 0x50c bytes
user32.dll!_DefDlgProcWorker(a)20() + 0x7f bytes
user32.dll!_DefDlgProcA(a)16() + 0x22 bytes
user32.dll!_InternalCallWinProc(a)20() + 0x28 bytes
user32.dll!_UserCallWinProcCheckWow(a)32() + 0xb7 bytes
user32.dll!_CallWindowProcAorW(a)24() + 0x51 bytes
user32.dll!_CallWindowProcA(a)20() + 0x1b bytes


Here are some from the thread with the assert:

> mfc80d.dll!CWnd::AssertValid() Line 886 + 0x19 bytes C++
mfc80d.dll!CDialog::AssertValid() Line 809 C++
mfc80d.dll!AfxAssertValidObject(const CObject * pOb=0x00111468, const
char * lpszFileName=0x781f42b0, int nLine=1693) Line 107 C++

mfc80d.dll!COleControlSite::XOleIPSite::GetWindowContext(IOleInPlaceFrame
* * ppFrame=0x20cbafe8, IOleInPlaceUIWindow * * ppDoc=0x20cbcfe8,
tagRECT * prectPos=0x1133fc10, tagRECT * prectClip=0x1133fc20, tagOIFI
* pFrameInfo=0x20cb8fd8) Line 1695 C++
rpcrt4.dll!_Invoke(a)12() + 0x30 bytes
rpcrt4.dll!_NdrStubCall2(a)16() + 0x215 bytes
rpcrt4.dll!_CStdStubBuffer_Invoke(a)12() + 0x82 bytes
ole32.dll!SyncStubInvoke() + 0x33 bytes
ole32.dll!StubInvoke() + 0x73 bytes
ole32.dll!CCtxComChnl::ContextInvoke() + 0xd2 bytes
ole32.dll!MTAInvoke() + 0x1a bytes
ole32.dll!AppInvoke() + 0x76 bytes
ole32.dll!ComInvokeWithLockAndIPID() + 0x23d bytes
ole32.dll!ComInvoke() + 0x5a bytes
ole32.dll!ThreadDispatch() + 0x1a bytes
ole32.dll!CRpcThread::WorkerLoop() + 0x1e bytes
ole32.dll!CRpcThreadCache::RpcWorkerThreadEntry() + 0x1b bytes
kernel32.dll!_BaseThreadStart@8() + 0x37 bytes

I don't understand where this thread came from.

Thanks

From: Scott McPhillips [MVP] on
sb wrote:
> I'm trying to get to the bottom of this assert in wincore.cpp:
>
> // should also be in the permanent or temporary handle map
> CHandleMap* pMap = afxMapHWND();
> ASSERT(pMap != NULL);
>
> The comments say "it is likely that you have passed a C++ object from
> one thread to another and have used that object in a way that was not
> intended."

Every window and control is tightly bound to the thread in which it is
created. MFC does not permit you to access any functions that affect
the window from a different thread.

--
Scott McPhillips [VC++ MVP]

From: sb on
My problem is that I don't think this second thread should be
there...it looks like a COM event is being received/fired when the
control is activated (DoVerb -5) on the main thread. The main thread
control is derived from the CDHtmlDialog class and I see that there is
an event sink inherited, but I don't understand how it all fits to
together and if it related to the assert on this second thread. Also,
the problem doesn't happen the first time the dialog with this control
is displayed, it happens the second time.

Thanks

Scott McPhillips [MVP] wrote:
> sb wrote:
> > I'm trying to get to the bottom of this assert in wincore.cpp:
> >
> > // should also be in the permanent or temporary handle map
> > CHandleMap* pMap = afxMapHWND();
> > ASSERT(pMap != NULL);
> >
> > The comments say "it is likely that you have passed a C++ object from
> > one thread to another and have used that object in a way that was not
> > intended."
>
> Every window and control is tightly bound to the thread in which it is
> created. MFC does not permit you to access any functions that affect
> the window from a different thread.
>
> --
> Scott McPhillips [VC++ MVP]