MFC之为对话框添加变量

进来一直在学MFC,现在基本都在VS2008下练习写一些小程序,偶尔也会在VC6.0下,很多教程都是在VC6.0下写的代码,但是做一个大工程的话,个人感觉VS还是比较好的。


顺便也发表一下自己的观点。带实验的时候看到一些刚接触C语言的同学就用VS,他们毫无编程经验,对C语言本身都是一知半解,写的又都是控制台程序,通常很小很小的程序,最多也就100行代码了,可是非要用VS,如此功能强大的VS让他们用来写hello world,我都感觉有些糟蹋了。通常情况下都是他们被VS难倒而不是C语言本身。我个人认为,在初学C、C++时,VC6.0就是一个很好的平台,即简单又便捷,当学到一定程度后,如果想研究VS,再去在VS平台上做东西,当然VC6.0也可以做很多东西,只是相对来说VS集成的东西更多更全。当然我不是说谁好谁坏,只是选择适合自己的才是明智的。


不扯废话了,上正题,说说今天我遇到的一个很foolish的问题。


我看了MFC的网络编程,模仿书上敲了一段代码,但是结果运行时,还未弹出对话框,就弹出了错误警告,如图:


点击重试跟踪进去,发现assert 的地方的代码是:

_AFXCMN_INLINE int CListCtrl::InsertColumn(int nCol, const LVCOLUMN* pColumn)
	{ ASSERT(::IsWindow(m_hWnd)); return (int) ::SendMessage(m_hWnd, LVM_INSERTCOLUMN, nCol, (LPARAM)pColumn); }

主要问题就是IsWindow(m_hWnd)上面,也就是我访问了一个非法的句柄。于是乎,老一套,设断点调试跟踪代码,跟踪发现在运行下面这段代码时便出问题了:

	CTest2Dlg dlg;
	m_pMainWnd = &dlg;
	INT_PTR nResponse = dlg.DoModal();

于是傻呵呵的去查DoModal()函数的详细说明,结果一无所获了。接下来苦思冥想,怎么也想不出问题在哪里。上网搜搜,也未搜到对应的答案,苦恼了。。。。


一狠心,重新建了一个工程,重头开始一点一点的试,写一段就调试运行一把,终于把问题找出来了。

我在对话框中添加了一个List Control控件,前面我写了一篇文章记述了关于访问控件的几种方法,在这里就不罗嗦了,有兴趣的可以看我之前的文章。有一种访问方式便是为控件添加一个变量,与控件绑定。而我在第一次建工程的时候,傻呵呵的手动去添加了,也就是直接在代码里添加的,结果少加了一句最关键的代码,也就是绑定的代码,如下:

void CTest2Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST1, m_PackList);
}

最关键的就是DDX_Control(pDX, IDC_LIST1, m_PackList);,我第一次的时候没有加这句话,所以就导致了变量m_PackList没有与控件IDC_LIST1绑定,而在后续使用的时候就使得系统不知道m_PackList是什么,在assert的时候,判断m_PackList也就不是一个window了,这样就出现了前面所说的情况,弹出了那个框框。。。。


那么手动为控件添加变量时都需要做哪些工作呢,在VS2008中,需要在两个地方添加代码,一个是dialog类中,声明一个与控件对应的public 控制变量,一个就是上面的定义绑定了。

在声明变量时,需要注意的是变量的类型要注意,一定要是控件对应的,否则白搭了。。。。。


下面来看看DDX_Control函数,其原型是:

void AFXAPI DDX_Control( CDataExchange* pDX, int nIDC, CWnd& rControl );

参数:
pDX 指向CDataExchange对象的指针。框架提供了这个对象以建立数据交换的环境,包括其方向。
nIDC 与控件属性相关的被子类化的控件的资源ID。
rControl 对对话框、表格视或控件视的成员变量的引用,将与该变量发生数据交换。

说明:
DDX_Control函数管理着在对话框、表格视或控件视中被子类化的控件与对话框、表格视或控件视的CWnd数据成员之间的数据交换。

到这,问题就算解决了,这种问题太不好找了,编译没有错误,费了好久好久。也可能是我还是生手,需要好好努力,等我成大牛了,也许这种问题i就不是问题了。


加油,向前走!

你可能感兴趣的:(MFC学习之路)