在VC6.0环境下出现错误如下:
出现这个错误,在网络上找了半天都解决不了。很纳闷的问题。于是自己搜索afxcmn.inl文件,找到:
c:\Program Files (x86)\Microsoft Visual Studio\VC98\MFC\Include\afxcmn.inl
在132行处找到如下:
_AFXCMN_INLINE int CListCtrl::GetItemCount() const
{ ASSERT(::IsWindow(m_hWnd)); return (int) ::SendMessage(m_hWnd, LVM_GETITEMCOUNT, 0, 0L); }
根据这个错误提示是CListCtrl控件的问题,通过调试发现如下代码出错:
LRESULT CGClientDlg::OnConnect(WPARAM wparam,LPARAM lparam)
{
CClientItem *Item = (CClientItem *)wparam;
// 下面这条语句注释掉就不会出错了
int nCnt = m_List.GetItemCount();
return 0;
}
LRESULT CGClientDlg::OnDisConn(WPARAM wparam,LPARAM lparam)
{
CClientItem *Item = (CClientItem *)wparam;
// 很纳闷这里不会出错
for (int i=0;i<m_List.GetItemCount();i++)
{
Item = (CClientItem*)m_List.GetItemData(i);
if(Item->m_ID== (int)wparam)
{
::closesocket(Item->GetSocket());
delete Item;
m_List.DeleteItem(i);
}
}
return 0;
}
根据这个判断应该是m_List在使用的时候之前窗体应该还没有创建完成,导致窗体句柄出错。
该错误在release版本不会出现,在debug版本才存在。
可是我的疑问是这个函数还没有调用不是,他只是一个自定义消息映射函数。
后面在这两个函数里面加入AfxMessageBox函数测试,奇怪的发现:
在窗体还没有创建之前就执行了OnConnect函数,窗体关闭后执行了OnDisConn,想不明白了,看来自己对MFC的消息循环理解还不够透彻。
于是乎,我看下消息定义代码如下:
#define MSG_CONNECT 0x01
#define MSG_DISCONN 0x02
于是就在想是不是这里,换一种定义方式:
#define MSG_CONNECT WM_USER+1
#define MSG_DISCONN WM_USER+2
设置完毕后,问题解决了。后面仔细想想可能是定义消息的顺序问题被被程序调用了。查了一下:
#define WM_CREATE 0x0001
#define WM_DESTROY 0x0002
这就解释了为什么创建窗体之前调用onconnect,而ondisconn在关闭后调用了。
至此,问题解决了,原理也明白了。