我创见一个对话框,CtesttDlg 类,但为什么我在外部写一个函数,里面写上这个CtesttDlg对像时,在调用这个对像

我创见一个对话框,CtesttDlg 类,但为什么我在外部写一个函数show(),里面写上这个CtesttDlg对像时,在调用这个对像上方法时,会报
for information on how your program can cause an assertion failure,see the visual c++ documentation on asserts
而且listbox.里也没有值
程序如下:
void show()
{
CtesttDlg test=new CtesttDlg();
testone();
}
void CtesttDlg::OnBnClickedButton1()
{ show();
// TODO: 在此添加控件通知处理程序代码
}

int CtesttDlg::testone(void)
{
m_listbox.AddString("我现身");
return 0;
}

第1个回答  2011-02-01
新建一个工程->MFCAppWizard[exe]->工程名Mybole->单文档应用程序

对话框有2种类型,模态和非模态

---

1 创建新对话框IDD_DIALOG1,然后创造一个新类CTestDlg(在对话框资源编辑器,双击2下),和它相关联起来。

2 新建一个菜单IDM_DIALOG(把弹出取消),标题:对话框。点击它的时候,显示我们新建的对话框。

3 在菜单资源编辑器,新建的菜单“对话框”上,右键点击类向导,做命令响应(COMMAND),VIEW类。

4 创建模态对话框

在void CMyboleView::OnDialog() 下写代码:

//view类并不知道CTestDlg,所以需要在view类.cpp包含它,#include "TestDlg.h"

CTestDlg dlg;//CTestDlg是自己新建对话框,新建的类
dlg.DoModal ();//创建摸态对话框

---

5 创建非模态对话框

BOOL Create( UINT nIDTemplate, CWnd* pParentWnd = NULL );
参数:对话框模版id;对话框父窗口的指针,如果为NULL,它的父窗口,就是框架窗口。

在void CMyboleView::OnDialog() 下写代码:

CTestDlg *pdlg=new CTestDlg();

pdlg->Create(IDD_DIALOG1,this);//创建非模态对话框,用view类作为它的父窗口,选this
pdlg->ShowWindow(SW_SHOW);//还要用ShowWindow,把它显示出来

//因为是用new操作符构建非模态对话框对象,因此必须在对话框关闭后,用delete操作符删除对话框对象

void CTestDlg::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class

CDialog::PostNcDestroy();
delete this; //删除对象本身
}

//覆盖OnOK这个成员函数,在OnOK内部调用DestroyWindow销毁窗口void CTestDlg::OnOK()
{
// TODO: Add extra validation here

CDialog::OnOK();
CDialog::DestroyWindow();
}

//覆盖OnCancel这个成员函数,在OnCancel内部调用DestroyWindow销毁窗口
void CTestDlg::OnCancel()
{
// TODO: Add extra cleanup here

CDialog::OnCancel();
CDialog::DestroyWindow();
}

//对话框右上角的关闭X按钮,
void CTestDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default

CDialog::OnClose();
DestroyWindow();

}

===

动态创建一个按钮

先在资源编辑器,增加一个按钮,然后做消息响应void CTestDlg::OnBtnAdd()。

在CTestDlg增加成员变量(全局变量),类型CButton,名称m_btn,权限private

利用CButton的成员函数Create。
BOOL Create( LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );
参数:控件文本,控件类型,控件矩形区域的大小,控件父窗口,id号可以随便写。

void CTestDlg::OnBtnAdd()
{

m_btn.Create("维新",BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,CRect(0,0,100,100),this,123);//动态创建按钮

}

//当我们再按按钮的时候,会发生非法错误,因为它重复创建了,所以就要判断一下,不让它多次创建。

第一个方法:
在CTestDlg增加一个成员变量,类型BOOL,名称m_blsCreate,权限private

在CTestDlg的构造函数进行初始化,m_blsCreate=FALSE;

在void CTestDlg::OnBtnAdd() 添加代码:

if(m_blsCreate==FALSE)
{
m_btn.Create("维新",BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
CRect(0,0,100,100),this,123);
m_blsCreate=TRUE;
}
else
{
m_btn.DestoryWindow();
m_blsCreate=FALSE;
}

第二个方法:

还要一个更便捷的方法,就是利用MFC里面保存的句柄
void CTestDlg::OnBtnAdd()
{
if(!m_btn.m_hWnd)//句柄没有值,创建
{
m_btn.Create("维新",BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
CRect(0,0,100,100),this,123);
}
else//否则,销毁窗口
{
m_btn.DestroyWindow();
}
}

---

动态编辑控件(static静态文本框)

需要先改变静态文本框的ID号,因为所有静态文本框的ID号都是一样的。
因为,这个控件不是用来响应鼠标点击消息的,可有些时候,我们就是想要它响应。

GetWindowText//获取文本
GetDlgItem//在对话框上面,获取控件指针。
SetWindowText//设置文本框内容

void CTestDlg::OnNumber1()
{
// TODO: Add your control notification handler code here
CString str;
if (GetDlgItem(IDC_NUMBER1)->GetWindowText(str),str=="number1:")
{
GetDlgItem(IDC_NUMBER1)->SetWindowText("数值1:");
}

else
{
GetDlgItem(IDC_NUMBER1)->SetWindowText("number1:");
}
}

备注:要让static静态文本框响应消息,需要在控件属性,复选上style(样式)->notif(通知)选项。

---

对话框控件操作

完成一个功能,将编辑框1+编辑框2的内容,放到编辑框3上面

第一种方法:

首先就要获取编辑框1和编辑框2的内容
void CTestDlg::OnBtnAdd()
{
int num1, num2, num3;
char ch1[10], ch2[10], ch3[10];

GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,10);
GetDlgItem(IDC_EDIT2)->GetWindowText(ch2,10);

num1=atoi(ch1);//atoi,c语言的一个函数;把一个字符串内容转换成整型
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);//itoa,c语言的一个函数;把一个整型内容转换成字符串

GetDlgItem(IDC_EDIT3)->SetWindowText(ch3);//把相加的结果放到编辑框3
}

第二种方法:

使用的函数:CWnd::GetDlgItemInt //获取一个控件文本,转换成整型返回

void CTestDlg::OnBtnAdd()
{
int num1, num2, num3;
num1=GetDlgItemInt(IDC_EDIT1);
num2=GetDlgItemInt(IDC_EDIT2);

num3=num1+num2;
SetDlgItemInt(IDC_EDIT3,num3);
}

第三种方法:将编辑框上的控件,关联一个成员变量

类向导(MFC ClassWizard)->成员变量(Member Variables)->Add Variables
IDC_EDIT1,名称m_num1,类型int。
IDC_EDIT2,名称m_num2,类型int。
IDC_EDIT3,名称m_num3,类型int。

void CTestDlg::OnBtnAdd()
{
UpdateData();
m_num3=m_num1+m_num2;
UpdateData(FALSE);
}

第四种方法:利用SendMessage发送一条消息获取,设置文本(WM_GETTEXT,WM_SETTEXT)

SendMessage(

HWND hWnd, //窗口句柄
UINT Msg, //WM_GETTEXT,WM_SETTEXT
WPARAM wParam, //你要拷贝多小数目的字符
LPARAM lParam //你所提供的buffer,用来保存窗口的文本
);

首先关联控件变量,也就是代表这个控件本身。

类向导(MFC ClassWizard)->成员变量(Member Variables)->Add Variables
IDC_EDIT1,名称m_edit1,Category:Control,类型CEdit。
IDC_EDIT2,名称m_edit2,Category:Control,类型CEdit。
IDC_EDIT3,名称m_edit3,Category:Control,类型CEdit。

void CTestDlg::OnBtnAdd()
{
int num1, num2, num3;
char ch1[10], ch2[10], ch3[10];

//以下方法4选1,功能是:利用WM_GETTEXT消息获取文本

::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);
::SendMessage(m_edit1.m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);
GetDlgItem(IDC_EDIT1)->SendMessage(WM_GETTEXT,10,(LPARAM)ch1);
m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);

m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);
m_edit2.SendMessage(WM_GETTEXT,10,(LPARAM)ch2);

num1=atoi(ch1);//atoi,c语言的一个函数;把一个字符串内容转换成整型
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);//itoa,c语言的一个函数;把一个整型内容转换成字符串

m_edit3.SendMessage(WM_SETTEXT,0,(LPARAM)ch3);//利用WM_SETTEXT消息设置文本

}

===============================================

完成对话框收缩和扩展

首先增加一个button(按钮),标题改为"收缩<<"。
当我们点击"收缩<<"按钮的时候,我们要将对话框切除一部分。
然后将按钮的标题改为"扩展>>"。
再点击"扩展>>"按钮的时候,还原整个对话框。

首先要完成文本的变换,可以给按钮增加一个点击消息事件响应。
双击"收缩<<"按钮,增加点击消息事件响应OnButton2()。

void CTestDlg::OnButton2()
{
// TODO: Add your control notification handler code here
CString str;

if (GetDlgItemText(IDC_BUTTON2,str),str=="收缩<<")//获取按钮文本
{
SetDlgItemText(IDC_BUTTON2,"扩展>>");//设置按钮文本
}

else
{
SetDlgItemText(IDC_BUTTON2,"收缩<<");
}
}

下面在对话框上面增加一个分隔符,用以表示切割的部分。
分隔符可以用图象控件(picture)来代替,在对话框窗口上面,将它拉成一条线。

然后改变它的属性,将它的ID号改为IDC_SEPARATOR。
在styles(样式),复选上sunken(凹陷)。
将分隔符隐藏,把visible(可见)的勾去掉。

static CRect rectLarge; //还原后的尺寸
static CRect rectSmall;//切割后的尺寸

if (rectLarge.IsRectNull())//判断矩形区域是否为空
{
CRect rectSeparator;
GetWindowRect(&rectLarge);//获取对话框原始区域大小
GetDlgItem(IDC_SEPARATOR)->GetWindowRect(&rectSeparator);//获取图象控件矩形区域

//为对话框切割空的尺寸(左上角,右下角坐标)赋值
rectSmall.left=rectLarge.left;
rectSmall.top=rectLarge.top;
rectSmall.right=rectLarge.right;
rectSmall.bottom=rectSeparator.bottom;
}

//完成收缩扩展功能
if (str=="收缩<<")
{
SetWindowPos(NULL,0,0,rectSmall.Width(),rectSmall.Height(),
SWP_NOMOVE | SWP_NOZORDER);
}
else
{
SetWindowPos(NULL,0,0,rectLarge.Width(),rectLarge.Height(),
SWP_NOMOVE | SWP_NOZORDER);
}

===============================================

编辑框按Enter键切换的方法

方法1:很麻烦,繁琐
void CTestDlg::OnOK()
{
// TODO: Add extra validation here

//CDialog::OnOK();
}

因为ok(确定)按钮是一个缺剩按钮,为了按下ok按钮之后,对话框不关闭。
所以要"//CDialog::OnOK();",注释起来。

SetWindowLong改变指定窗口属性
LONG SetWindowLong(

HWND hWnd, //要改变的窗口句柄
int nIndex, //设定一个值的偏移量,GWL_WNDPROC,设定新的窗口过程地址。
LONG dwNewLong //新的窗口过程地址
);

在CTestDlg增加消息处理WM_INITDIALOG。

WNDPROC prevProc;
LRESULT CALLBACK WinSunProc(

HWND hwnd, // handle of window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)

{
if(uMsg==WM_CHAR && wParam==0x0d)//判断输入是否为字符和回车
{
::SetFocus(::GetNextWindow(hwnd,GW_HWNDNEXT));//让输入焦点移动到下一个编辑框
return 1;
}
else
{
return prevProc(hwnd,uMsg,wParam,lParam);
}
}

BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// TODO: Add extra initialization here

prevProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd,GWL_WNDPROC,
(long)WinSunProc);//改变窗口过程

return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

最后要改变编辑框1(IDC_EDIT1)的属性,样式(style)->多行(Multiline)打上勾。

方法2:简便很多

先取消编辑框1(IDC_EDIT1)属性->样式(style)->多行(Multiline)

void CTestDlg::OnOK()
{
// TODO: Add extra validation here

GetNextDlgTabItem(GetFocus())->SetFocus();//获取当前具有焦点的控件,设置焦点
//CDialog::OnOK();
}
相似回答