一个跨类调用的小问题,求高手~

时间:2021-10-31 17:33:14
我创建了两个对话框:一个主对话框,假设类名为CMainDlg;一个子对话框,假设类名为COtherDlg;
为什么我在子对话框中定义的函数( 假设此函数名为function(a,b))在主对话框中调用时一直出错?
头文件什么的都包含了。我在主对话框中的调用代码是这样写的:
void CXXDlg::OnBnClickedButton()
{
COtherDlg dlg;
dlg.function(m, n); //m,n都是赋了值的实参
}
调试的时候没有错,编译的时候出现错误:"Debug Assertion failed"之类的,还有警告框:"遇到不适当的参数!"
请问这是什么问题啊。我试过在子对话框中调用时没有错的,为什么不能跨类调用啊?我现在必须跨类调用啊,该怎么改啊? 

16 个解决方案

#1


比如,你这个function里面去修改某个控件的状态
那么在子对话框里就会使用this->m_hWnd这样类似的东西
然后你在主对话框中定义的dlg中的dlg.m_hWnd已经不是原来那个窗口的句柄了。
简单的说就是你重新定义的dlg和你之前创建的那个子对话框并不是同一个对象,
所以他们包含的资源也是不一样的。
底层函数在断言的时候就会出现那个错误,比如会有这样的断言:ASSERT(::IsWindow(m_hWnd))

--------------------------------------------------------------------------------------------

这种情况你可以SendMessage交给子对话框去调用。

#2


空引用,找不到要调用哪个子窗口。用FindWindow找到子窗口,通过返回的HWND来调用该窗口里的function

#3


调用时未生成子窗口,因此被调函数中不能涉及子窗口的任何资源。

#4


也可以用回调函数

#5


有没有代码,可以参考下啊?怎么找到子窗口的句柄?
引用 1 楼  的回复:
比如,你这个function里面去修改某个控件的状态
那么在子对话框里就会使用this->m_hWnd这样类似的东西
然后你在主对话框中定义的dlg中的dlg.m_hWnd已经不是原来那个窗口的句柄了。
简单的说就是你重新定义的dlg和你之前创建的那个子对话框并不是同一个对象,
所以他们包含的资源也是不一样的。
底层函数在断言的时候就会出现那个错误,比如会有这样的断言:ASSERT(::……

#6


原因我知道了,但是用代码咋写呢?
引用 2 楼  的回复:
空引用,找不到要调用哪个子窗口。用FindWindow找到子窗口,通过返回的HWND来调用该窗口里的function

#7


你这种情况时候父对话框创建子对话框的时候把子对话框的对象指针保存下来,这样需要的时候就通过这个指针来调用function

#8


HWND m_wnd;
m_wnd = ::FindWindow(NULL, _T("childdlg's caption"));
CWnd* ptempwnd = CWnd::FromHandle (m_wnd);
ptempwnd->function(m, n);

#9


您好,出现了这个错误:error C2039: “function”: 不是“CWnd”的成员,是啥问题呢?
引用 8 楼  的回复:
HWND m_wnd;
m_wnd = ::FindWindow(NULL, _T("childdlg's caption"));
CWnd* ptempwnd = CWnd::FromHandle (m_wnd);
ptempwnd->function(m, n);

#10


关键是function里面你都干什么了
如果你操作了控件那肯定会报错啊
因为窗口没建立
所以控件的指针都为空
如果没有和控件相关的操作不应该会有问题

#11


dlg.function(m, n); 

把代码贴出来

#12


引用 9 楼  的回复:
您好,出现了这个错误:error C2039: “function”: 不是“CWnd”的成员,是啥问题呢?引用 8 楼  的回复:
HWND m_wnd;
m_wnd = ::FindWindow(NULL, _T("childdlg's caption"));
CWnd* ptempwnd = CWnd::FromHandle (m_wnd);
ptempwnd->function(……

用这个就行了啊,你出错的原因是你的function怎么写的,调用的是什么的代码,是自定义的代码还是控件的

#13


把两个Cwnd替换成你的子窗口类名试试! 
引用 9 楼  的回复:
您好,出现了这个错误:error C2039: “function”: 不是“CWnd”的成员,是啥问题呢?引用 8 楼  的回复:
HWND m_wnd;
m_wnd = ::FindWindow(NULL, _T("childdlg's caption"));
CWnd* ptempwnd = CWnd::FromHandle (m_wnd);
ptempwnd->function(……

#14


引用 10 楼  的回复:
关键是function里面你都干什么了
如果你操作了控件那肯定会报错啊
因为窗口没建立
所以控件的指针都为空
如果没有和控件相关的操作不应该会有问题

function函数类容如下:

//const int nMaxValue = 8888;
    m_Progress.SetRange32(0,nMaxValue);
    for(int i = 0; i <= nMaxValue; i++)
    {
CString percent;
m_Progress.SetPos(i);
        percent.Format("%.0f%%", 100.0f*(float)i/(float)nMaxValue); //用百分比显示进度 2012-5-7
m_Number.SetWindowText(percent);
if(i == nCurValue)
break;
    }

m_Progress是进度条控件变量。那如果我使用了控件,要在主窗口中调用这个函数该怎么办呢?感谢你了啊。

#15


你的这段代码有问题。因为你还没有生成对话框就调用了设计对话框中控件的函数。

void CXXDlg::OnBnClickedButton()
{
COtherDlg dlg;
dlg.function(m, n); //m,n都是赋了值的实参
}

建议楼主把 COtherDlg dlg;这句代码放到头文件中。
然后把上面点击按钮的代码更改为

void CXXDlg::OnBnClickedButton()
{
dlg.Create(***,this);
dlg.function(m, n); //m,n都是赋了值的实参
}

其中***为子对话框的id。

#16


引用 14 楼  的回复:
引用 10 楼  的回复:
关键是function里面你都干什么了
如果你操作了控件那肯定会报错啊
因为窗口没建立
所以控件的指针都为空
如果没有和控件相关的操作不应该会有问题

function函数类容如下:C/C++ code

//const int nMaxValue = 8888;
    m_Progress.SetRange32(0,nMaxValue);
    ……

你没发这么使用
窗口都没创建怎么可能访问到对话框中的控件呢
你要实现什么需求

#1


比如,你这个function里面去修改某个控件的状态
那么在子对话框里就会使用this->m_hWnd这样类似的东西
然后你在主对话框中定义的dlg中的dlg.m_hWnd已经不是原来那个窗口的句柄了。
简单的说就是你重新定义的dlg和你之前创建的那个子对话框并不是同一个对象,
所以他们包含的资源也是不一样的。
底层函数在断言的时候就会出现那个错误,比如会有这样的断言:ASSERT(::IsWindow(m_hWnd))

--------------------------------------------------------------------------------------------

这种情况你可以SendMessage交给子对话框去调用。

#2


空引用,找不到要调用哪个子窗口。用FindWindow找到子窗口,通过返回的HWND来调用该窗口里的function

#3


调用时未生成子窗口,因此被调函数中不能涉及子窗口的任何资源。

#4


也可以用回调函数

#5


有没有代码,可以参考下啊?怎么找到子窗口的句柄?
引用 1 楼  的回复:
比如,你这个function里面去修改某个控件的状态
那么在子对话框里就会使用this->m_hWnd这样类似的东西
然后你在主对话框中定义的dlg中的dlg.m_hWnd已经不是原来那个窗口的句柄了。
简单的说就是你重新定义的dlg和你之前创建的那个子对话框并不是同一个对象,
所以他们包含的资源也是不一样的。
底层函数在断言的时候就会出现那个错误,比如会有这样的断言:ASSERT(::……

#6


原因我知道了,但是用代码咋写呢?
引用 2 楼  的回复:
空引用,找不到要调用哪个子窗口。用FindWindow找到子窗口,通过返回的HWND来调用该窗口里的function

#7


你这种情况时候父对话框创建子对话框的时候把子对话框的对象指针保存下来,这样需要的时候就通过这个指针来调用function

#8


HWND m_wnd;
m_wnd = ::FindWindow(NULL, _T("childdlg's caption"));
CWnd* ptempwnd = CWnd::FromHandle (m_wnd);
ptempwnd->function(m, n);

#9


您好,出现了这个错误:error C2039: “function”: 不是“CWnd”的成员,是啥问题呢?
引用 8 楼  的回复:
HWND m_wnd;
m_wnd = ::FindWindow(NULL, _T("childdlg's caption"));
CWnd* ptempwnd = CWnd::FromHandle (m_wnd);
ptempwnd->function(m, n);

#10


关键是function里面你都干什么了
如果你操作了控件那肯定会报错啊
因为窗口没建立
所以控件的指针都为空
如果没有和控件相关的操作不应该会有问题

#11


dlg.function(m, n); 

把代码贴出来

#12


引用 9 楼  的回复:
您好,出现了这个错误:error C2039: “function”: 不是“CWnd”的成员,是啥问题呢?引用 8 楼  的回复:
HWND m_wnd;
m_wnd = ::FindWindow(NULL, _T("childdlg's caption"));
CWnd* ptempwnd = CWnd::FromHandle (m_wnd);
ptempwnd->function(……

用这个就行了啊,你出错的原因是你的function怎么写的,调用的是什么的代码,是自定义的代码还是控件的

#13


把两个Cwnd替换成你的子窗口类名试试! 
引用 9 楼  的回复:
您好,出现了这个错误:error C2039: “function”: 不是“CWnd”的成员,是啥问题呢?引用 8 楼  的回复:
HWND m_wnd;
m_wnd = ::FindWindow(NULL, _T("childdlg's caption"));
CWnd* ptempwnd = CWnd::FromHandle (m_wnd);
ptempwnd->function(……

#14


引用 10 楼  的回复:
关键是function里面你都干什么了
如果你操作了控件那肯定会报错啊
因为窗口没建立
所以控件的指针都为空
如果没有和控件相关的操作不应该会有问题

function函数类容如下:

//const int nMaxValue = 8888;
    m_Progress.SetRange32(0,nMaxValue);
    for(int i = 0; i <= nMaxValue; i++)
    {
CString percent;
m_Progress.SetPos(i);
        percent.Format("%.0f%%", 100.0f*(float)i/(float)nMaxValue); //用百分比显示进度 2012-5-7
m_Number.SetWindowText(percent);
if(i == nCurValue)
break;
    }

m_Progress是进度条控件变量。那如果我使用了控件,要在主窗口中调用这个函数该怎么办呢?感谢你了啊。

#15


你的这段代码有问题。因为你还没有生成对话框就调用了设计对话框中控件的函数。

void CXXDlg::OnBnClickedButton()
{
COtherDlg dlg;
dlg.function(m, n); //m,n都是赋了值的实参
}

建议楼主把 COtherDlg dlg;这句代码放到头文件中。
然后把上面点击按钮的代码更改为

void CXXDlg::OnBnClickedButton()
{
dlg.Create(***,this);
dlg.function(m, n); //m,n都是赋了值的实参
}

其中***为子对话框的id。

#16


引用 14 楼  的回复:
引用 10 楼  的回复:
关键是function里面你都干什么了
如果你操作了控件那肯定会报错啊
因为窗口没建立
所以控件的指针都为空
如果没有和控件相关的操作不应该会有问题

function函数类容如下:C/C++ code

//const int nMaxValue = 8888;
    m_Progress.SetRange32(0,nMaxValue);
    ……

你没发这么使用
窗口都没创建怎么可能访问到对话框中的控件呢
你要实现什么需求