我在一个MFC的对话框程序里动态创建4个Radio单选按钮,是用指针和new生成。但在类的另一个成员函数里再使用指针去控制4个Radio按钮的时候,却激发了断言。代码如下://**************************************************
//头文件的定义部分如下:
class CCreateButton : public CWnd
{
public:
//……
CButton *m_BnRadio1;
CButton *m_BnRadio2;
CButton *m_BnRadio3;
CButton *m_BnRadio4;
//单击Radio的响应函数
afx_msg void OnBnRadioClked(UINT m_BnRaID);
//……
}
//*******************************************************
//*******************************************************
//.cpp文件定义如下:
//定义控件ID
#define IDB_RABUTTON1 310
#define IDB_RABUTTON2 311
#define IDB_RABUTTON3 312
#define IDB_RABUTTON4 313BEGIN_MESSAGE_MAP(CCreateButton,CWnd)
//……
ON_CONTROL_RANGE(BN_CLICKED,IDB_RABUTTON1,IDB_RABUTTON4,&CCreateButton::OnBnRadioClked)
//……
END_MESSAGE_MAP()CCreateButton::CCreateButton(CWnd *pParent /* = NULL */)
{
//……
//初始化指针为空
m_BnRadio1 = NULL;
m_BnRadio2 = NULL;
m_BnRadio3 = NULL;
m_BnRadio4 = NULL;
}
void CCreateButton::CreateButton1()
{
//…… //新建4个单选控件
m_BnRadio1 = new CButton;
m_BnRadio1->Create(_T("图1"),WS_GROUP | WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(0,370,80,395),m_WndCreate,IDB_RABUTTON1);
m_BnRadio2 = new CButton;
m_BnRadio2->Create(_T("图2"),WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(100,370,180,395),m_WndCreate,IDB_RABUTTON2);
m_BnRadio3 = new CButton;
m_BnRadio3->Create(_T("图3"),WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(200,370,280,395),m_WndCreate,IDB_RABUTTON3);
m_BnRadio4 = new CButton;
m_BnRadio4->Create(_T("图4"),WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(300,370,380,395),m_WndCreate,IDB_RABUTTON4);
//预置第一Radio为选中
m_BnRadio1->SetCheck(true);
m_BnRadio2->SetCheck(false);
m_BnRadio3->SetCheck(false);
m_BnRadio4->SetCheck(false);
//顺利执行,没有发生断言 //……
}
void CCreateButton::OnBnRadioClked(UINT m_BnRaID) //响应4个Radio控件的单击事件
{
switch(m_BnRaID)
{
case IDB_RABUTTON1:
{
/*m_BnRadio1->SetCheck(true);
m_BnRadio2->SetCheck(false);
m_BnRadio3->SetCheck(false);
m_BnRadio4->SetCheck(false);*/
//触发断言如下:***************************************
//_AFXWIN_INLINE void CButton::SetCheck(int nCheck)
//{ ASSERT(::IsWindow(m_hWnd)); ::SendMessage(m_hWnd, BM_SETCHECK, nCheck, 0); }
//**********************************************************
//下面的可以执行
((CButton*)GetDlgItem(IDB_RABUTTON1))->SetCheck(true);
((CButton*)GetDlgItem(IDB_RABUTTON2))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON3))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON4))->SetCheck(false);
//……
break;
}
case IDB_RABUTTON2:
{
/*m_BnRadio1->SetCheck(false);
m_BnRadio2->SetCheck(true);
m_BnRadio3->SetCheck(false);
m_BnRadio4->SetCheck(false);*/
//激发断言,同上
//下面的可以执行 ((CButton*)GetDlgItem(IDB_RABUTTON1))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON2))->SetCheck(true);
((CButton*)GetDlgItem(IDB_RABUTTON3))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON4))->SetCheck(false);
//……
break;
}
case IDB_RABUTTON3:
{
/*m_BnRadio1->SetCheck(false);
m_BnRadio2->SetCheck(false);
m_BnRadio3->SetCheck(true);
m_BnRadio4->SetCheck(false);*/
//激发断言,同1 //下面的可以执行 ((CButton*)GetDlgItem(IDB_RABUTTON1))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON2))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON3))->SetCheck(true);
((CButton*)GetDlgItem(IDB_RABUTTON4))->SetCheck(false);
//……
break;
}
case IDB_RABUTTON4:
{
/*m_BnRadio1->SetCheck(false);
m_BnRadio2->SetCheck(false);
m_BnRadio3->SetCheck(false);
m_BnRadio4->SetCheck(true);*/
//激发断言,同1 //下面的可以执行 ((CButton*)GetDlgItem(IDB_RABUTTON1))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON2))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON3))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON4))->SetCheck(true);
//……
break;
}
}
}
void CCreateButton::OnClose()
{
//……
//释放内存
if(m_BnRadio1)
delete m_BnRadio1;
if(m_BnRadio2)
delete m_BnRadio2;
if(m_BnRadio3)
delete m_BnRadio3;
if(m_BnRadio4)
delete m_BnRadio4;}//*******************************************************
我在其他地方没有对4个指针进行过任何操作。为什么在创建按钮的成员函数里可以使用指针对控件进行控制,而在类的另一个成员函数里就不能使用这4个指针对控件进行控制了呢?这4个指针是类的成员变量,应该还是指向相应的控件吧?但是,我用断点跟踪,发现在创建控件的函数里,指针是指向相应地址的。但在另一个成员函数里(即响应4个Radio单击事件的函数)4个指针却是空地址。我在其他地方没有对指针进行过任何操作。这是什么原因呢?希望各位指教……
//头文件的定义部分如下:
class CCreateButton : public CWnd
{
public:
//……
CButton *m_BnRadio1;
CButton *m_BnRadio2;
CButton *m_BnRadio3;
CButton *m_BnRadio4;
//单击Radio的响应函数
afx_msg void OnBnRadioClked(UINT m_BnRaID);
//……
}
//*******************************************************
//*******************************************************
//.cpp文件定义如下:
//定义控件ID
#define IDB_RABUTTON1 310
#define IDB_RABUTTON2 311
#define IDB_RABUTTON3 312
#define IDB_RABUTTON4 313BEGIN_MESSAGE_MAP(CCreateButton,CWnd)
//……
ON_CONTROL_RANGE(BN_CLICKED,IDB_RABUTTON1,IDB_RABUTTON4,&CCreateButton::OnBnRadioClked)
//……
END_MESSAGE_MAP()CCreateButton::CCreateButton(CWnd *pParent /* = NULL */)
{
//……
//初始化指针为空
m_BnRadio1 = NULL;
m_BnRadio2 = NULL;
m_BnRadio3 = NULL;
m_BnRadio4 = NULL;
}
void CCreateButton::CreateButton1()
{
//…… //新建4个单选控件
m_BnRadio1 = new CButton;
m_BnRadio1->Create(_T("图1"),WS_GROUP | WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(0,370,80,395),m_WndCreate,IDB_RABUTTON1);
m_BnRadio2 = new CButton;
m_BnRadio2->Create(_T("图2"),WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(100,370,180,395),m_WndCreate,IDB_RABUTTON2);
m_BnRadio3 = new CButton;
m_BnRadio3->Create(_T("图3"),WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(200,370,280,395),m_WndCreate,IDB_RABUTTON3);
m_BnRadio4 = new CButton;
m_BnRadio4->Create(_T("图4"),WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(300,370,380,395),m_WndCreate,IDB_RABUTTON4);
//预置第一Radio为选中
m_BnRadio1->SetCheck(true);
m_BnRadio2->SetCheck(false);
m_BnRadio3->SetCheck(false);
m_BnRadio4->SetCheck(false);
//顺利执行,没有发生断言 //……
}
void CCreateButton::OnBnRadioClked(UINT m_BnRaID) //响应4个Radio控件的单击事件
{
switch(m_BnRaID)
{
case IDB_RABUTTON1:
{
/*m_BnRadio1->SetCheck(true);
m_BnRadio2->SetCheck(false);
m_BnRadio3->SetCheck(false);
m_BnRadio4->SetCheck(false);*/
//触发断言如下:***************************************
//_AFXWIN_INLINE void CButton::SetCheck(int nCheck)
//{ ASSERT(::IsWindow(m_hWnd)); ::SendMessage(m_hWnd, BM_SETCHECK, nCheck, 0); }
//**********************************************************
//下面的可以执行
((CButton*)GetDlgItem(IDB_RABUTTON1))->SetCheck(true);
((CButton*)GetDlgItem(IDB_RABUTTON2))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON3))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON4))->SetCheck(false);
//……
break;
}
case IDB_RABUTTON2:
{
/*m_BnRadio1->SetCheck(false);
m_BnRadio2->SetCheck(true);
m_BnRadio3->SetCheck(false);
m_BnRadio4->SetCheck(false);*/
//激发断言,同上
//下面的可以执行 ((CButton*)GetDlgItem(IDB_RABUTTON1))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON2))->SetCheck(true);
((CButton*)GetDlgItem(IDB_RABUTTON3))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON4))->SetCheck(false);
//……
break;
}
case IDB_RABUTTON3:
{
/*m_BnRadio1->SetCheck(false);
m_BnRadio2->SetCheck(false);
m_BnRadio3->SetCheck(true);
m_BnRadio4->SetCheck(false);*/
//激发断言,同1 //下面的可以执行 ((CButton*)GetDlgItem(IDB_RABUTTON1))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON2))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON3))->SetCheck(true);
((CButton*)GetDlgItem(IDB_RABUTTON4))->SetCheck(false);
//……
break;
}
case IDB_RABUTTON4:
{
/*m_BnRadio1->SetCheck(false);
m_BnRadio2->SetCheck(false);
m_BnRadio3->SetCheck(false);
m_BnRadio4->SetCheck(true);*/
//激发断言,同1 //下面的可以执行 ((CButton*)GetDlgItem(IDB_RABUTTON1))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON2))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON3))->SetCheck(false);
((CButton*)GetDlgItem(IDB_RABUTTON4))->SetCheck(true);
//……
break;
}
}
}
void CCreateButton::OnClose()
{
//……
//释放内存
if(m_BnRadio1)
delete m_BnRadio1;
if(m_BnRadio2)
delete m_BnRadio2;
if(m_BnRadio3)
delete m_BnRadio3;
if(m_BnRadio4)
delete m_BnRadio4;}//*******************************************************
我在其他地方没有对4个指针进行过任何操作。为什么在创建按钮的成员函数里可以使用指针对控件进行控制,而在类的另一个成员函数里就不能使用这4个指针对控件进行控制了呢?这4个指针是类的成员变量,应该还是指向相应的控件吧?但是,我用断点跟踪,发现在创建控件的函数里,指针是指向相应地址的。但在另一个成员函数里(即响应4个Radio单击事件的函数)4个指针却是空地址。我在其他地方没有对指针进行过任何操作。这是什么原因呢?希望各位指教……
CButton *m_BnRadio2;
CButton *m_BnRadio3;
CButton *m_BnRadio4;
改成CWnd
中将创建按钮(这个函数是什么时候调用的,我看不懂),当你调用CCreateButton::OnBnRadioClked时,应该指针值还是NULL,也就是说窗口没有创建,根据MSDN,IsWindow的返回值:“If the window handle does not identify an existing window, the return value is zero. ”
所以会触发断言。
如果大家有时间的话,也可以试一试。我用的是Win 7系统,vs2008
源代码:http://download.csdn.net/source/2757357
内有说明。有什么问题随时可以和我联系。小弟万分感谢!
void CClassPointDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码 //新建子窗口和4个Radio单选控件
/*m_WndCreate = new CCreateButton;
m_WndCreate->CreateButton1();*/
CCreateButton m_WndCreate;
m_WndCreate.CreateButton1();
}
CreateButton1的时候当然没有问题,m_WndCreate对象还存在。
出了这个函数后,m_WndCreate对象是局部变量,就被回收了啊。
/*m_WndCreate = new CCreateButton;
m_WndCreate->CreateButton1();*/
//CCreateButton的析构函数不调用,直到释放内存才调用
//说明一直在内存中存在
CCreateButton m_WndCreate;
m_WndCreate.CreateButton1();
//调用完成后调用析构函数,关闭程序是也调用析构函数为什么会出现这种原因啊!用指针new一个CCreateButton,它一直在内存里存在,为什么成员变量却没有了生命呢??
VC6源代码:http://download.csdn.net/source/2757695
//自己定义的文件,创建按钮和相应函数
#include "stdafx.h"
#include "CMyHeadFile.h"
#include "Resource.h"#define WNDCHILD1 2010
#define IDB_RABUTTON1 310
#define IDB_RABUTTON2 311
#define IDB_RABUTTON3 312
#define IDB_RABUTTON4 313
CButton *m_BnRadio1;
CButton *m_BnRadio2;
CButton *m_BnRadio3;
CButton *m_BnRadio4;CCreateButton::CCreateButton(CWnd *pParent /* = NULL */)
{
m_WndCreate = NULL;
m_BnRadio1 = NULL;
m_BnRadio2 = NULL;
m_BnRadio3 = NULL;
m_BnRadio4 = NULL;
}将定义放到这里就可以了
修改如下:
void CCreateButton::CreateButton1()
{
//新建对话框层
// m_WndCreate = new CCreateButton;
Create(NULL,_T("CHILDWINDOW"),WS_DLGFRAME | WS_CHILD | WS_VISIBLE,
CRect(150,100,650,500),AfxGetMainWnd(),WNDCHILD1);
//新建4个单选控件
m_BnRadio1 = new CButton;
m_BnRadio1.Create(_T("图1"),WS_GROUP | WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(0,370,80,395),this,IDB_RABUTTON1);
m_BnRadio2 = new CButton;
m_BnRadio2.Create(_T("图2"),WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(100,370,180,395),this,IDB_RABUTTON2);
m_BnRadio3 = new CButton;
m_BnRadio3.Create(_T("图3"),WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(200,370,280,395),this,IDB_RABUTTON3);
m_BnRadio4 = new CButton;
m_BnRadio4.Create(_T("图4"),WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(300,370,380,395),this,IDB_RABUTTON4);
m_BnRadio1->SetCheck(true);
m_BnRadio2->SetCheck(false);
m_BnRadio3->SetCheck(false);
m_BnRadio4->SetCheck(false);
CenterWindow(NULL);
ShowWindow(SW_SHOW);
}你在CCreateButton类中,又创建一个m_WndCreate = new CCreateButton;真是莫名奇妙啊。根本不需要它啊。
public:
CCreateButton *m_WndCreate;
在CCreateButton::CCreateButton(CWnd *pParent /* = NULL */)
{
m_WndCreate = NULL;
//……
}
又把指针置空了,在CCreateButton::CreateButton1()里不new新建一个CCreateButton,怎么可以直接用m_WndCreate新建一个子窗口啊??
这个关系还需要自己慢慢去理清,光这么说,估计你一时也绕不出来。