我在主程序MainFrm.cpp中分割2X1窗口,左边二行,右边一列,然后启动线程tread.
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext *pContext)
{//分割2X1窗口,左边二行,右边一列;左上行是CMytoolView,左下行是infoscrol,右边一列是CAdver1
CRect rect;
GetClientRect(&rect);
if(m_wndSplitter1.CreateStatic(this,1,2)==NULL) return FALSE;
m_wndSplitter1.CreateView(0,1,RUNTIME_CLASS(CAdver1),CSize(rect.Width()/4,rect.Height()),pContext);
if(m_wndSplitter2.CreateStatic(&m_wndSplitter1,2,1,WS_CHILD|WS_VISIBLE,m_wndSplitter1.IdFromRowCol(0,0))==NULL)//从第一次分割的窗口中,再分割
return FALSE;
m_wndSplitter2.CreateView(0,0,RUNTIME_CLASS(CMytoolView),CSize(rect.Width()*3/4,rect.Height()*4/5),pContext);
m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(infoscrol),CSize(rect.Width()/4,rect.Height()*1/5),pContext); m_wndSplitter1.SetColumnInfo( 0,rect.Width()*3/4,0 );//m_wndSplitter1是父窗口,如果对m_wndSplitter2进行列操作是不能分割这里的列宽度,因为列分割是由m_wndSplitter1产生的。
m_wndSplitter1.RecalcLayout();
pt=*pContext;//保留三分视图的上下文,在mytoolview.cpp中(数据流检测)变更视图类型时使用
return TRUE;//不再调用基类的OnCreateClient函数 // return CFrameWnd::OnCreateClient(lpcs, pContext);
} int CMainFrame::OnEditBook()//我自己定义的一个函数
{
AfxBeginThread(tread,this); //启动线程
} UINT tread(LPVOID pParam)//子线程
{
CMainFrame* mt=(CMainFrame*)pParam;
CMytoolView* ct=(CMytoolView*)mt->m_wndSplitter2.GetPane(0,0);
//程序运行到上面这句,就会提示出错 wincore.cpp line 894
}
程序在Debug状态下编译全部通过,运行时,就会提示出错wincore.cpp line 894。void CWnd::AssertValid() const
{
if (m_hWnd == NULL)
return; // null (unattached) windows are valid // check for special wnd??? values
ASSERT(HWND_TOP == NULL); // same as desktop
if (m_hWnd == HWND_BOTTOM)
ASSERT(this == &CWnd::wndBottom);
else if (m_hWnd == HWND_TOPMOST)
ASSERT(this == &CWnd::wndTopMost);
else if (m_hWnd == HWND_NOTOPMOST)
ASSERT(this == &CWnd::wndNoTopMost);
else
{
// should be a normal window
ASSERT(::IsWindow(m_hWnd)); // should also be in the permanent or temporary handle map
CHandleMap* pMap = afxMapHWND();
ASSERT(pMap != NULL); CObject* p; // 在下面一句出错
ASSERT((p = pMap->LookupPermanent(m_hWnd)) != NULL ||
(p = pMap->LookupTemporary(m_hWnd)) != NULL);
ASSERT((CWnd*)p == this); // must be us // Note: if either of the above asserts fire and you are
// writing a multithreaded application, 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.
// (only simple inline wrapper functions should be used)
//
// In general, CWnd objects should be passed by HWND from
// one thread to another. The receiving thread can wrap
// the HWND with a CWnd object by using CWnd::FromHandle.
//
// It is dangerous to pass C++ objects from one thread to
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext *pContext)
{//分割2X1窗口,左边二行,右边一列;左上行是CMytoolView,左下行是infoscrol,右边一列是CAdver1
CRect rect;
GetClientRect(&rect);
if(m_wndSplitter1.CreateStatic(this,1,2)==NULL) return FALSE;
m_wndSplitter1.CreateView(0,1,RUNTIME_CLASS(CAdver1),CSize(rect.Width()/4,rect.Height()),pContext);
if(m_wndSplitter2.CreateStatic(&m_wndSplitter1,2,1,WS_CHILD|WS_VISIBLE,m_wndSplitter1.IdFromRowCol(0,0))==NULL)//从第一次分割的窗口中,再分割
return FALSE;
m_wndSplitter2.CreateView(0,0,RUNTIME_CLASS(CMytoolView),CSize(rect.Width()*3/4,rect.Height()*4/5),pContext);
m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(infoscrol),CSize(rect.Width()/4,rect.Height()*1/5),pContext); m_wndSplitter1.SetColumnInfo( 0,rect.Width()*3/4,0 );//m_wndSplitter1是父窗口,如果对m_wndSplitter2进行列操作是不能分割这里的列宽度,因为列分割是由m_wndSplitter1产生的。
m_wndSplitter1.RecalcLayout();
pt=*pContext;//保留三分视图的上下文,在mytoolview.cpp中(数据流检测)变更视图类型时使用
return TRUE;//不再调用基类的OnCreateClient函数 // return CFrameWnd::OnCreateClient(lpcs, pContext);
} int CMainFrame::OnEditBook()//我自己定义的一个函数
{
AfxBeginThread(tread,this); //启动线程
} UINT tread(LPVOID pParam)//子线程
{
CMainFrame* mt=(CMainFrame*)pParam;
CMytoolView* ct=(CMytoolView*)mt->m_wndSplitter2.GetPane(0,0);
//程序运行到上面这句,就会提示出错 wincore.cpp line 894
}
程序在Debug状态下编译全部通过,运行时,就会提示出错wincore.cpp line 894。void CWnd::AssertValid() const
{
if (m_hWnd == NULL)
return; // null (unattached) windows are valid // check for special wnd??? values
ASSERT(HWND_TOP == NULL); // same as desktop
if (m_hWnd == HWND_BOTTOM)
ASSERT(this == &CWnd::wndBottom);
else if (m_hWnd == HWND_TOPMOST)
ASSERT(this == &CWnd::wndTopMost);
else if (m_hWnd == HWND_NOTOPMOST)
ASSERT(this == &CWnd::wndNoTopMost);
else
{
// should be a normal window
ASSERT(::IsWindow(m_hWnd)); // should also be in the permanent or temporary handle map
CHandleMap* pMap = afxMapHWND();
ASSERT(pMap != NULL); CObject* p; // 在下面一句出错
ASSERT((p = pMap->LookupPermanent(m_hWnd)) != NULL ||
(p = pMap->LookupTemporary(m_hWnd)) != NULL);
ASSERT((CWnd*)p == this); // must be us // Note: if either of the above asserts fire and you are
// writing a multithreaded application, 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.
// (only simple inline wrapper functions should be used)
//
// In general, CWnd objects should be passed by HWND from
// one thread to another. The receiving thread can wrap
// the HWND with a CWnd object by using CWnd::FromHandle.
//
// It is dangerous to pass C++ objects from one thread to
{
CMainFrame* mt=(CMainFrame*)pParam;
CWnd* pWnd = mt->m_wndSplitter2.GetPane(0,0);
CMytoolView* ct = DYNAMIC_DOWNCAST( CMytoolView, pWnd );
}试试改成上面的可以不?
{
CMainFrame* mt=(CMainFrame*)pParam;
CHandleMap* pMap = afxMapHWND();
pMap->SetPermanent(mt->m_hWnd,mt);
CMytoolView* ct=(CMytoolView*)mt->m_wndSplitter2.GetPane(0,0); }
'afxMapHWND' : undeclared identifier
error C2440: 'initializing' : cannot convert from 'int' to 'class CHandleMap *'
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
error C2027: use of undefined type 'CHandleMap'
你看看这个http://blog.vckbase.com/arong/archive/2009/05/17/15578.html
void CWnd::AssertValid() const 是哪个窗口调用的
如果是主窗口就把主窗口放到map中去(好像不是主窗口)你可以CSplitterWnd放到map中去试一下,我看了大概是getpane里面有句ASSERT_VALID(this)导致的问题
pMap->SetPermanent(mt->m_hWnd,mt);
==》pMap->SetPermanent(mt->m_wndSplitter2.m_hWnd,&mt->m_wndSplitter2);