我的主程序里有一个对话框进行参数设置。因为参数几百个,故弹出一个对话框里用一个tab控件弄了几页来显示参数。
当然在主程序里有个按钮按下后,
m_para.DoModal();
来显示弹出对话框在弹出对话框里,
初始化OnInitDialog()有:
m_tab.InsertItem(0,_T("基本参数"));
m_tab.InsertItem(1,_T("报警参数"));
在tab控件和各页面弄了一个对话框,没法子,VC就是这么做的。
basicdlg.Create(IDD_BASIC,GetDlgItem(IDC_PARA));
warndlg.Create(IDD_WARN,GetDlgItem(IDC_PARA));
下面啰里啰索一大堆废话,也就是把对话框显示出来的控制
basicdlg.UpdateData(FALSE);
warndlg.UpdateData(FALSE);
basicdlg.MoveWindow(&rs);
warndlg.MoveWindow(&rs);
basicdlg.ShowWindow(true);
warndlg.ShowWindow(false);
m_tab.SetCurSel(0);最后我要退出这个对话框回到主界面
void PARA_DLG::OnBnClickedOk()
{
basicdlg.DestroyWindow();
warndlg.DestroyWindow();
}一切都很好,界面出来了,tab控件都可以切换。
当我第二次按弹出这个对话框按钮时,发现进不去,调试时发现当程序跑到初始化basicdlg.Create(IDD_BASIC,GetDlgItem(IDC_PARA));时就会死掉不动了,又发现退出时加了一个bool量来下列函数返回值
bool atemp;
atemp=warndlg.DestroyWindow();
atemp=basicdlg.DestroyWindow();
都返回false,即失败了,
应该是warndlg,basicdlg没退出,故无法再行创建,请问各位大虾如何处理才好,谢谢
当然在主程序里有个按钮按下后,
m_para.DoModal();
来显示弹出对话框在弹出对话框里,
初始化OnInitDialog()有:
m_tab.InsertItem(0,_T("基本参数"));
m_tab.InsertItem(1,_T("报警参数"));
在tab控件和各页面弄了一个对话框,没法子,VC就是这么做的。
basicdlg.Create(IDD_BASIC,GetDlgItem(IDC_PARA));
warndlg.Create(IDD_WARN,GetDlgItem(IDC_PARA));
下面啰里啰索一大堆废话,也就是把对话框显示出来的控制
basicdlg.UpdateData(FALSE);
warndlg.UpdateData(FALSE);
basicdlg.MoveWindow(&rs);
warndlg.MoveWindow(&rs);
basicdlg.ShowWindow(true);
warndlg.ShowWindow(false);
m_tab.SetCurSel(0);最后我要退出这个对话框回到主界面
void PARA_DLG::OnBnClickedOk()
{
basicdlg.DestroyWindow();
warndlg.DestroyWindow();
}一切都很好,界面出来了,tab控件都可以切换。
当我第二次按弹出这个对话框按钮时,发现进不去,调试时发现当程序跑到初始化basicdlg.Create(IDD_BASIC,GetDlgItem(IDC_PARA));时就会死掉不动了,又发现退出时加了一个bool量来下列函数返回值
bool atemp;
atemp=warndlg.DestroyWindow();
atemp=basicdlg.DestroyWindow();
都返回false,即失败了,
应该是warndlg,basicdlg没退出,故无法再行创建,请问各位大虾如何处理才好,谢谢
{
basicdlg.DestroyWindow();
warndlg.DestroyWindow();
}不明白要Destroy什么?
可以不用它的,但如何解决第二次到basicdlg.Create时程序死掉的问题呢?
可以不用它的,但如何解决第二次到basicdlg.Create时程序死掉的问题呢?
class PARA_DLG : public CDialog
{
DECLARE_DYNAMIC(PARA_DLG)public:
PARA_DLG(CWnd* pParent = NULL); // 标准构造函数
virtual ~PARA_DLG(); BASIC basicdlg;
MARK_DLG dlg;
NOFLIGHT_DLG noflightdlg;
OTHER_DLG otherdlg;
WARN_DLG warndlg;// 对话框数据
enum { IDD = IDD_PARA };protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP()
public:
CTabCtrl m_tab;
virtual BOOL OnInitDialog();
afx_msg void OnTcnSelchangePara(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnBnClickedOk();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnBnClickedCancel();
};结构是:
主maindlg上一个按钮启动paradlg,
paradlg上有一个tab控件m_tab.
tab控件有5个页面,每个页面对应一个对话框,paradlg的OnInitDialog里create了几个对话框,第一次运行时可以的。第二次运行时,再到create代码处就死了。呜呜呜....
切望大侠指点,万分痛苦中。如果不行的话,只能把这个paradlg参数对话框写成一个单独程序,用主程序来启动了。这应该没问题吧。但改动工作量巨大啊。
5个对话框的父窗口都是m_tab。
关闭时m_tab是如何处理的
猜想是m_tab或basicdlg等对话框实例没卸掉的缘故,故在OnOK里加了destroy语句,结果还是不行,包括enddialog都试过了,如下所示。搞不定啊。
void PARA_DLG::OnBnClickedOk()
{
//otherdlg.CloseWindow();
//warndlg.CloseWindow();
//basicdlg.CloseWindow();
//dlg.CloseWindow();
//noflightdlg.CloseWindow(); otherdlg.OnBnClickedCancel();
warndlg.OnBnClickedCancel();
basicdlg.OnBnClickedCancel();
dlg.OnBnClickedCancel();
noflightdlg.OnBnClickedCancel();/* otherdlg.Detach();
warndlg.Detach();
basicdlg.Detach();
dlg.Detach();
noflightdlg.Detach(); *//* otherdlg.EndDialog(IDCANCEL);
warndlg.EndDialog(IDCANCEL);
basicdlg.EndDialog(IDCANCEL);
dlg.EndDialog(IDCANCEL);
noflightdlg.EndDialog(IDCANCEL); */ //bool atemp;
/* atemp=otherdlg.DestroyWindow();
atemp=warndlg.DestroyWindow();
atemp=basicdlg.DestroyWindow();
atemp=dlg.DestroyWindow();
atemp=noflightdlg.DestroyWindow(); */ OnOK();
}
因为 OnSeletChange会用到。
在OnSeletChange中:
1.delete all dlgs
if(IsWindow(m_dlg1.m_hwnd)) DestroyWindow(m_dlg1.m_hWnd);
if(IsWindow(m_dlg2.m_hwnd)) DestroyWindow(m_dlg2.m_hWnd);
....
2.产生新的:
CRect rc;
GetClientRect(&rc);
rc.top +=20;
//
int now=GetCurSel();
switch(now)
{
case 0:
m_dlg1.Create(MAKEINTRESOURCE(IDD_DIALOG1),this);
m_dlg1.MoveWindow(rc.left,rc.top,rc.Width(),rc.Height())
m_dlg1.ShowWindow(SW_SHOW);
break;
....
}
刚才看了一个股票的源代码,它的“实战操作”和:“策略分析”都是用tab的。从代码上来看是没有对话框,直接用button,listcontrol去show和hide干的。
不过偶既已日暮而途穷,余故倒行而逆施之。
BASIC basicdlg;
MARK_DLG dlg;
NOFLIGHT_DLG noflightdlg;
OTHER_DLG otherdlg;
WARN_DLG warndlg;//如果要Create,必须弄成指针.
//顺序是 new...Create....DestroyWindow....delete...
basicdlg.Create(IDD_BASIC,GetDlgItem(IDC_PARA));
warndlg.Create(IDD_WARN,GetDlgItem(IDC_PARA));
根据您所说的,我去掉了 OnInitDialog();里的dlg语句,结果直接死机,一次都跑不起来。
关于new指针,我是这样理解的,供指正
如果不用指针,在函数里,如int a;那么因为是局部变量,当函数结束时它就失效了。
如果用指针,在函数里应是这样定义int * pa=new int[arraysize];函数结束时你要记住delete.否则内存泄露
所以这时我多用int a 而不用指针形式
if(IsWindow(m_dlg1.m_hwnd)) DestroyWindow(m_dlg1.m_hWnd);
出现编译错误
1>.\MyTabCtrl.cpp(80) : error C2660: 'CWnd::DestroyWindow' : function does not take 1 arguments
斗胆改之为:
if(IsWindow(m_dlg1.m_hwnd)) m_dlg1.DestroyWindow();是否可行。
即为:
void CMyTabCtrl::OnTcnSelchange(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 在此添加控件通知处理程序代码
if(IsWindow(basicdlg.m_hWnd)) basicdlg.DestroyWindow();
.
.
.
}
basicdlg.DestroyWindow();
对的。思路:
尽管有5个dlg,在tab上显示的就一个。
可以不断地destroy和create但,如果tab切换时,把原来的dlg destroy,会使用户的输入丢失,当然也可以在切换前保留用户输入,create时重新初始化dlg,这样不是很麻烦吗,不如叫老的对话框隐藏好,切换回来不必初始化。所以主对话框初始化时把Tab insertitem 好,把dlg 产生好, 其中一个与当前tab绑定,其余的都隐藏。
切换时,隐藏老的,显示当前的
//如果不是Create出来的,肯定是这里有一条错了.
basicdlg.UpdateData(FALSE);
warndlg.UpdateData(FALSE);如果没有切换标签,默认的只创建了第1个窗口, 其他窗口还没创建自然不能UpdateData了.
你的对话框数据应该放在子窗口的Oninitdialog里面,不要在标签的主窗口里面。
所以换取数据的时候还要判断点了哪些标签.
建议去看一下m_tab的源代码,或者找类似的源代码.