MFC 控件类指针、new和GetDlgItem

haogeai123 2010-10-14 03:40:24
我在一个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 313

BEGIN_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个指针却是空地址。我在其他地方没有对指针进行过任何操作。这是什么原因呢?希望各位指教……
...全文
581 45 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
45 条回复
切换为时间正序
请发表友善的回复…
发表回复
haogeai123 2010-10-15
  • 打赏
  • 举报
回复
谢谢!结贴了!非常感谢“快乐鹦鹉”,于此表示膜拜!
快乐鹦鹉 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 43 楼 haogeai123 的回复:]
我明白了,就是说,我在使用CCreateButton类的时候就自动生成了一个对象,我在类里面再定义一个对象是完全不必要的。对吗?
[/Quote]
是的。你自己也解释不通啊。这个子对象算什么身份呢?你的功能就是在一个窗口上放四个radio,CCreateButton本身就代表这个窗口,四个radio的父对象应该是它。
haogeai123 2010-10-15
  • 打赏
  • 举报
回复
我明白了,就是说,我在使用CCreateButton类的时候就自动生成了一个对象,我在类里面再定义一个对象是完全不必要的。对吗?
快乐鹦鹉 2010-10-15
  • 打赏
  • 举报
回复
你这又困惑于类和实例的关系中了。你在CCreateButton类中又定义一个CCreateButton实例。m_WndCreate = NULL;只是将这个实例设置为空,并不是把当前这个类实例设置为空啊。你这个CCreateButton本身就是窗口类了,怎么会在它内部又去定义一个本身类实例呢?
这个关系还需要自己慢慢去理清,光这么说,估计你一时也绕不出来。
haogeai123 2010-10-15
  • 打赏
  • 举报
回复
100分,已经加到顶了!谢谢各位。尤其是“快乐鹦鹉”。不过,等我的最后一个疑问解决了就结贴!分数一定会相应加到各位的“账号”里的。
haogeai123 2010-10-15
  • 打赏
  • 举报
回复
好的!马上加分!不过,能不能帮忙解决完我上面的疑问啊?
haogeai123 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 happyparrot 的回复:]
终于找到你的毛病了。晕死啊。
修改如下:
void CCreateButton::CreateButton1()
{
//新建对话框层
// m_WndCreate = new CCreateButton;
Create(NULL,_T("CHILDWINDOW"),WS_DLGFRAME | WS_CHILD | WS_VISIBLE,
CRect(150,100,650,500)……
[/Quote]
谢谢!不过我还有一点疑问:m_WndCreate在类的声明为:
public:
CCreateButton *m_WndCreate;
在CCreateButton::CCreateButton(CWnd *pParent /* = NULL */)
{
m_WndCreate = NULL;
//……
}
又把指针置空了,在CCreateButton::CreateButton1()里不new新建一个CCreateButton,怎么可以直接用m_WndCreate新建一个子窗口啊??
快乐鹦鹉 2010-10-15
  • 打赏
  • 举报
回复
费劲,加分
快乐鹦鹉 2010-10-15
  • 打赏
  • 举报
回复
加分吧。其实原因在于Radio创建时指定的父对象不是Radio本身所在的类,而是这个类的一个实例对象,只不过两者是同一个类的实例。
fgsdcfgfsddfc 2010-10-15
  • 打赏
  • 举报
回复
说实话,这个我也不怎么清楚,你看你调用完 CreateButton1()后,是不是退出了CCreateButton类了,大概是因为这样吧,说的可能不对。如果你不是新建一个类,直接在CClassPointDlg类里面实现的话就没有这种情况了。
qiuhuncl 2010-10-15
  • 打赏
  • 举报
回复
路过看不懂啊,,,,
快乐鹦鹉 2010-10-15
  • 打赏
  • 举报
回复
终于找到你的毛病了。晕死啊。
修改如下:
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;真是莫名奇妙啊。根本不需要它啊。
快乐鹦鹉 2010-10-15
  • 打赏
  • 举报
回复
测试发现,在CreateButton1函数和OnBnRadioClked函数中,this指针值不相同。
haogeai123 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 syhkgyxy2010 的回复:]
C/C++ code

//自己定义的文件,创建按钮和相应函数
#include "stdafx.h"
#include "CMyHeadFile.h"
#include "Resource.h"

#define WNDCHILD1 2010
#define IDB_RABUTTON1 310
……
[/Quote]
这样是一个全局变量。那为什么在类里面就不行呢??类的成员变量的生命周期不是和类的对象一样的吗?当类的对象还有生命,该对象的成员不是都有生命的吗??
fgsdcfgfsddfc 2010-10-15
  • 打赏
  • 举报
回复
vc6.0应该也一样。
fgsdcfgfsddfc 2010-10-15
  • 打赏
  • 举报
回复
vs2008的。。
fgsdcfgfsddfc 2010-10-15
  • 打赏
  • 举报
回复

//自己定义的文件,创建按钮和相应函数
#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;
}

将定义放到这里就可以了。。。
haogeai123 2010-10-15
  • 打赏
  • 举报
回复
因为编译工具的原因,我用VC6新建了一个工程。但问题依然。深切希望有高手可以出来解决。
VC6源代码:http://download.csdn.net/source/2757695
haogeai123 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 happyparrot 的回复:]
我把这个类放到VC6工程中,m_WndCreate.CreateButton1();后根本没有反应,没有显示任何窗口啊。
[/Quote]
这是为什么??我一直用vs2008,很少用VC6,我再用VC6试试……
快乐鹦鹉 2010-10-15
  • 打赏
  • 举报
回复
我把这个类放到VC6工程中,m_WndCreate.CreateButton1();后根本没有反应,没有显示任何窗口啊。
加载更多回复(24)

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧